mirror of
https://github.com/paboyle/Grid.git
synced 2025-10-24 09:44:47 +01:00
Compare commits
1 Commits
feature/fe
...
dirac-ITT-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9df685cde |
12
TODO
12
TODO
@@ -3,19 +3,19 @@ TODO:
|
|||||||
|
|
||||||
Large item work list:
|
Large item work list:
|
||||||
|
|
||||||
1)- BG/Q port and check ; Andrew says ok.
|
1)- BG/Q port and check
|
||||||
2)- Christoph's local basis expansion Lanczos
|
2)- Christoph's local basis expansion Lanczos
|
||||||
--
|
3)- Precision conversion and sort out localConvert <-- partial
|
||||||
3a)- RNG I/O in ILDG/SciDAC (minor)
|
|
||||||
3b)- Precision conversion and sort out localConvert <-- partial/easy
|
- Consistent linear solver flop count/rate -- PARTIAL, time but no flop/s yet
|
||||||
3c)- Consistent linear solver flop count/rate -- PARTIAL, time but no flop/s yet
|
|
||||||
4)- Physical propagator interface
|
4)- Physical propagator interface
|
||||||
5)- Conserved currents
|
5)- Conserved currents
|
||||||
6)- Multigrid Wilson and DWF, compare to other Multigrid implementations
|
6)- Multigrid Wilson and DWF, compare to other Multigrid implementations
|
||||||
7)- HDCR resume
|
7)- HDCR resume
|
||||||
|
|
||||||
Recent DONE
|
Recent DONE
|
||||||
-- MultiRHS with spread out extra dim -- Go through filesystem with SciDAC I/O ; <-- DONE ; bmark cori
|
|
||||||
|
-- MultiRHS with spread out extra dim -- Go through filesystem with SciDAC I/O. <--- DONE
|
||||||
-- Lanczos Remove DenseVector, DenseMatrix; Use Eigen instead. <-- DONE
|
-- Lanczos Remove DenseVector, DenseMatrix; Use Eigen instead. <-- DONE
|
||||||
-- GaugeFix into central location <-- DONE
|
-- GaugeFix into central location <-- DONE
|
||||||
-- Scidac and Ildg metadata handling <-- DONE
|
-- Scidac and Ildg metadata handling <-- DONE
|
||||||
|
|||||||
@@ -51,13 +51,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|
||||||
std::vector<int> latt4 = GridDefaultLatt();
|
std::vector<int> latt4 = GridDefaultLatt();
|
||||||
int Ls=16;
|
const int Ls=16;
|
||||||
for(int i=0;i<argc;i++)
|
|
||||||
if(std::string(argv[i]) == "-Ls"){
|
|
||||||
std::stringstream ss(argv[i+1]); ss >> Ls;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||||
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||||
|
|||||||
@@ -1,190 +0,0 @@
|
|||||||
#include <Grid/Grid.h>
|
|
||||||
#include <sstream>
|
|
||||||
using namespace std;
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
template<class d>
|
|
||||||
struct scal {
|
|
||||||
d internal;
|
|
||||||
};
|
|
||||||
|
|
||||||
Gamma::Algebra Gmu [] = {
|
|
||||||
Gamma::Algebra::GammaX,
|
|
||||||
Gamma::Algebra::GammaY,
|
|
||||||
Gamma::Algebra::GammaZ,
|
|
||||||
Gamma::Algebra::GammaT
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef typename GparityDomainWallFermionF::FermionField GparityLatticeFermionF;
|
|
||||||
typedef typename GparityDomainWallFermionD::FermionField GparityLatticeFermionD;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc,&argv);
|
|
||||||
|
|
||||||
int Ls=16;
|
|
||||||
for(int i=0;i<argc;i++)
|
|
||||||
if(std::string(argv[i]) == "-Ls"){
|
|
||||||
std::stringstream ss(argv[i+1]); ss >> Ls;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "Ls = " << Ls << std::endl;
|
|
||||||
|
|
||||||
std::vector<int> latt4 = GridDefaultLatt();
|
|
||||||
|
|
||||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplexF::Nsimd()),GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
|
||||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
|
||||||
|
|
||||||
std::vector<int> seeds4({1,2,3,4});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Initialising 4d RNG" << std::endl;
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
std::cout << GridLogMessage << "Initialising 5d RNG" << std::endl;
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
std::cout << GridLogMessage << "Initialised RNGs" << std::endl;
|
|
||||||
|
|
||||||
GparityLatticeFermionF src (FGrid); random(RNG5,src);
|
|
||||||
RealD N2 = 1.0/::sqrt(norm2(src));
|
|
||||||
src = src*N2;
|
|
||||||
|
|
||||||
GparityLatticeFermionF result(FGrid); result=zero;
|
|
||||||
GparityLatticeFermionF ref(FGrid); ref=zero;
|
|
||||||
GparityLatticeFermionF tmp(FGrid);
|
|
||||||
GparityLatticeFermionF err(FGrid);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Drawing gauge field" << std::endl;
|
|
||||||
LatticeGaugeFieldF Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4,Umu);
|
|
||||||
std::cout << GridLogMessage << "Random gauge initialised " << std::endl;
|
|
||||||
|
|
||||||
RealD mass=0.1;
|
|
||||||
RealD M5 =1.8;
|
|
||||||
|
|
||||||
RealD NP = UGrid->_Nprocessors;
|
|
||||||
RealD NN = UGrid->NodeCount();
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "* Benchmarking DomainWallFermion::Dhop "<<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplexF::Nsimd()<<std::endl;
|
|
||||||
#ifdef GRID_OMP
|
|
||||||
if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
|
|
||||||
if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
|
|
||||||
#endif
|
|
||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
|
|
||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using Nc=3 WilsonKernels" <<std::endl;
|
|
||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3 WilsonKernels" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<< "* SINGLE/SINGLE"<<std::endl;
|
|
||||||
GparityDomainWallFermionF Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
|
|
||||||
int ncall =1000;
|
|
||||||
if (1) {
|
|
||||||
FGrid->Barrier();
|
|
||||||
Dw.ZeroCounters();
|
|
||||||
Dw.Dhop(src,result,0);
|
|
||||||
std::cout<<GridLogMessage<<"Called warmup"<<std::endl;
|
|
||||||
double t0=usecond();
|
|
||||||
for(int i=0;i<ncall;i++){
|
|
||||||
__SSC_START;
|
|
||||||
Dw.Dhop(src,result,0);
|
|
||||||
__SSC_STOP;
|
|
||||||
}
|
|
||||||
double t1=usecond();
|
|
||||||
FGrid->Barrier();
|
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
|
||||||
double flops=2*1344*volume*ncall;
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
|
||||||
// std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
|
|
||||||
// std::cout<<GridLogMessage << "norm ref "<< norm2(ref)<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s = "<< flops/(t1-t0)<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s per rank = "<< flops/(t1-t0)/NP<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s per node = "<< flops/(t1-t0)/NN<<std::endl;
|
|
||||||
Dw.Report();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<< "* SINGLE/HALF"<<std::endl;
|
|
||||||
GparityDomainWallFermionFH DwH(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
|
|
||||||
if (1) {
|
|
||||||
FGrid->Barrier();
|
|
||||||
DwH.ZeroCounters();
|
|
||||||
DwH.Dhop(src,result,0);
|
|
||||||
double t0=usecond();
|
|
||||||
for(int i=0;i<ncall;i++){
|
|
||||||
__SSC_START;
|
|
||||||
DwH.Dhop(src,result,0);
|
|
||||||
__SSC_STOP;
|
|
||||||
}
|
|
||||||
double t1=usecond();
|
|
||||||
FGrid->Barrier();
|
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
|
||||||
double flops=2*1344*volume*ncall;
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called half prec comms Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s = "<< flops/(t1-t0)<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s per rank = "<< flops/(t1-t0)/NP<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s per node = "<< flops/(t1-t0)/NN<<std::endl;
|
|
||||||
DwH.Report();
|
|
||||||
}
|
|
||||||
|
|
||||||
GridCartesian * UGrid_d = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplexD::Nsimd()),GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian * UrbGrid_d = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid_d);
|
|
||||||
GridCartesian * FGrid_d = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid_d);
|
|
||||||
GridRedBlackCartesian * FrbGrid_d = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid_d);
|
|
||||||
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<< "* DOUBLE/DOUBLE"<<std::endl;
|
|
||||||
GparityLatticeFermionD src_d(FGrid_d);
|
|
||||||
precisionChange(src_d,src);
|
|
||||||
|
|
||||||
LatticeGaugeFieldD Umu_d(UGrid_d);
|
|
||||||
precisionChange(Umu_d,Umu);
|
|
||||||
|
|
||||||
GparityLatticeFermionD result_d(FGrid_d);
|
|
||||||
|
|
||||||
GparityDomainWallFermionD DwD(Umu_d,*FGrid_d,*FrbGrid_d,*UGrid_d,*UrbGrid_d,mass,M5);
|
|
||||||
if (1) {
|
|
||||||
FGrid_d->Barrier();
|
|
||||||
DwD.ZeroCounters();
|
|
||||||
DwD.Dhop(src_d,result_d,0);
|
|
||||||
std::cout<<GridLogMessage<<"Called warmup"<<std::endl;
|
|
||||||
double t0=usecond();
|
|
||||||
for(int i=0;i<ncall;i++){
|
|
||||||
__SSC_START;
|
|
||||||
DwD.Dhop(src_d,result_d,0);
|
|
||||||
__SSC_STOP;
|
|
||||||
}
|
|
||||||
double t1=usecond();
|
|
||||||
FGrid_d->Barrier();
|
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
|
||||||
double flops=2*1344*volume*ncall;
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
|
||||||
// std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
|
|
||||||
// std::cout<<GridLogMessage << "norm ref "<< norm2(ref)<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s = "<< flops/(t1-t0)<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s per rank = "<< flops/(t1-t0)/NP<<std::endl;
|
|
||||||
std::cout<<GridLogMessage << "mflop/s per node = "<< flops/(t1-t0)/NN<<std::endl;
|
|
||||||
DwD.Report();
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout << latt_size.back() << "\t\t";
|
std::cout << latt_size.back() << "\t\t";
|
||||||
|
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
LatticeGaugeField Umu(&Grid); random(pRNG,Umu);
|
LatticeGaugeField Umu(&Grid); random(pRNG,Umu);
|
||||||
|
|||||||
@@ -1,26 +1,25 @@
|
|||||||
#include <Grid/Hadrons/Modules/MLoop/NoiseLoop.hpp>
|
#include <Grid/Hadrons/Modules/MAction/DWF.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MFermion/GaugeProp.hpp>
|
#include <Grid/Hadrons/Modules/MAction/Wilson.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MContraction/Meson.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MContraction/DiscLoop.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MContraction/Baryon.hpp>
|
#include <Grid/Hadrons/Modules/MContraction/Baryon.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/DiscLoop.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/Gamma3pt.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/Meson.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp>
|
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp>
|
#include <Grid/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MContraction/Gamma3pt.hpp>
|
#include <Grid/Hadrons/Modules/MFermion/GaugeProp.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/Z2.hpp>
|
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/SeqGamma.hpp>
|
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/Point.hpp>
|
#include <Grid/Hadrons/Modules/MGauge/StochEm.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/Wall.hpp>
|
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/Laplacian.hpp>
|
#include <Grid/Hadrons/Modules/MLoop/NoiseLoop.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MScalar/ChargedProp.hpp>
|
#include <Grid/Hadrons/Modules/MScalar/ChargedProp.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MScalar/FreeProp.hpp>
|
#include <Grid/Hadrons/Modules/MScalar/FreeProp.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MScalar/Scalar.hpp>
|
#include <Grid/Hadrons/Modules/MScalar/Scalar.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MAction/DWF.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MAction/Wilson.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/StochEm.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MSink/Point.hpp>
|
#include <Grid/Hadrons/Modules/MSink/Point.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/Point.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/SeqGamma.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/Wall.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/Z2.hpp>
|
||||||
|
|||||||
@@ -1,153 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MSource/Laplacian.hpp
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Guido Cossu <guido.cossu@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 Hadrons_MSource_Laplacian_hpp_
|
|
||||||
#define Hadrons_MSource_Laplacian_hpp_
|
|
||||||
|
|
||||||
#include <Grid/Hadrons/Global.hpp>
|
|
||||||
#include <Grid/Hadrons/Module.hpp>
|
|
||||||
#include <Grid/Hadrons/ModuleFactory.hpp>
|
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Laplacian smearing source
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
* options:
|
|
||||||
- source: name of source object to be smeared (string)
|
|
||||||
- N: number of steps (integer)
|
|
||||||
- alpha: smearing parameter (real)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Laplace smearing operator *
|
|
||||||
******************************************************************************/
|
|
||||||
BEGIN_MODULE_NAMESPACE(MSource)
|
|
||||||
|
|
||||||
class LaplacianPar : Serializable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LaplacianPar,
|
|
||||||
std::string, source,
|
|
||||||
std::string, gauge,
|
|
||||||
unsigned int, N,
|
|
||||||
double, alpha);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename FImpl>
|
|
||||||
class TLaplacian : public Module<LaplacianPar>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FERM_TYPE_ALIASES(FImpl, );
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructor
|
|
||||||
TLaplacian(const std::string name);
|
|
||||||
// destructor
|
|
||||||
virtual ~TLaplacian(void) = default;
|
|
||||||
// dependency relation
|
|
||||||
virtual std::vector<std::string> getInput(void);
|
|
||||||
virtual std::vector<std::string> getOutput(void);
|
|
||||||
// setup
|
|
||||||
virtual void setup(void);
|
|
||||||
// execution
|
|
||||||
virtual void execute(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
MODULE_REGISTER_NS(LaplaceSmearing, TLaplacian<FIMPL>, MSource);
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* TLaplacian template implementation *
|
|
||||||
******************************************************************************/
|
|
||||||
// constructor /////////////////////////////////////////////////////////////////
|
|
||||||
template <typename FImpl>
|
|
||||||
TLaplacian<FImpl>::TLaplacian(const std::string name)
|
|
||||||
: Module<LaplacianPar>(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
|
||||||
template <typename FImpl>
|
|
||||||
std::vector<std::string> TLaplacian<FImpl>::getInput(void)
|
|
||||||
{
|
|
||||||
std::vector<std::string> in = {par().source, par().gauge};
|
|
||||||
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FImpl>
|
|
||||||
std::vector<std::string> TLaplacian<FImpl>::getOutput(void)
|
|
||||||
{
|
|
||||||
std::vector<std::string> out = {getName()};
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup ///////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename FImpl>
|
|
||||||
void TLaplacian<FImpl>::setup(void)
|
|
||||||
{
|
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
|
||||||
template <typename FImpl>
|
|
||||||
void TLaplacian<FImpl>::execute(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
FermionField source(env().getGrid()), tmp(env().getGrid());
|
|
||||||
PropagatorField &SmrSrc = *env().template createLattice<PropagatorField>(getName());
|
|
||||||
PropagatorField &fullSrc = *env().template getObject<PropagatorField>(par().source);
|
|
||||||
auto &U = *env().template getObject<LatticeGaugeField>(par().gauge);
|
|
||||||
Laplacian<FImpl> LaplaceOperator(env().getGrid());
|
|
||||||
LaplaceOperator.ImportGauge(U);
|
|
||||||
double prefactor = par().alpha / (double)(par().N);
|
|
||||||
|
|
||||||
for (unsigned int s = 0; s < Ns; ++s)
|
|
||||||
{
|
|
||||||
for (unsigned int c = 0; c < Nc; ++c)
|
|
||||||
{
|
|
||||||
PropToFerm(source, fullSrc, s, c);
|
|
||||||
for (int smr = 0; smr < par().N; ++smr)
|
|
||||||
{
|
|
||||||
LaplaceOperator.M(source, tmp);
|
|
||||||
source += prefactor * tmp;
|
|
||||||
}
|
|
||||||
FermToProp(SmrSrc, source, s, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
|
||||||
|
|
||||||
#endif // Hadrons_MSource_Z2_hpp_
|
|
||||||
@@ -1,39 +1,38 @@
|
|||||||
modules_cc =\
|
modules_cc =\
|
||||||
|
Modules/MContraction/WeakHamiltonianEye.cc \
|
||||||
Modules/MContraction/WeakHamiltonianNonEye.cc \
|
Modules/MContraction/WeakHamiltonianNonEye.cc \
|
||||||
Modules/MContraction/WeakNeutral4ptDisc.cc \
|
Modules/MContraction/WeakNeutral4ptDisc.cc \
|
||||||
Modules/MContraction/WeakHamiltonianEye.cc \
|
Modules/MGauge/Load.cc \
|
||||||
Modules/MScalar/FreeProp.cc \
|
|
||||||
Modules/MScalar/ChargedProp.cc \
|
|
||||||
Modules/MGauge/Unit.cc \
|
|
||||||
Modules/MGauge/Random.cc \
|
Modules/MGauge/Random.cc \
|
||||||
Modules/MGauge/StochEm.cc \
|
Modules/MGauge/StochEm.cc \
|
||||||
Modules/MGauge/Load.cc
|
Modules/MGauge/Unit.cc \
|
||||||
|
Modules/MScalar/ChargedProp.cc \
|
||||||
|
Modules/MScalar/FreeProp.cc
|
||||||
|
|
||||||
modules_hpp =\
|
modules_hpp =\
|
||||||
Modules/MLoop/NoiseLoop.hpp \
|
Modules/MAction/DWF.hpp \
|
||||||
Modules/MFermion/GaugeProp.hpp \
|
Modules/MAction/Wilson.hpp \
|
||||||
Modules/MContraction/WeakHamiltonian.hpp \
|
|
||||||
Modules/MContraction/Meson.hpp \
|
|
||||||
Modules/MContraction/DiscLoop.hpp \
|
|
||||||
Modules/MContraction/WeakHamiltonianEye.hpp \
|
|
||||||
Modules/MContraction/Baryon.hpp \
|
Modules/MContraction/Baryon.hpp \
|
||||||
|
Modules/MContraction/DiscLoop.hpp \
|
||||||
|
Modules/MContraction/Gamma3pt.hpp \
|
||||||
|
Modules/MContraction/Meson.hpp \
|
||||||
|
Modules/MContraction/WeakHamiltonian.hpp \
|
||||||
|
Modules/MContraction/WeakHamiltonianEye.hpp \
|
||||||
Modules/MContraction/WeakHamiltonianNonEye.hpp \
|
Modules/MContraction/WeakHamiltonianNonEye.hpp \
|
||||||
Modules/MContraction/WeakNeutral4ptDisc.hpp \
|
Modules/MContraction/WeakNeutral4ptDisc.hpp \
|
||||||
Modules/MContraction/Gamma3pt.hpp \
|
Modules/MFermion/GaugeProp.hpp \
|
||||||
Modules/MSource/Z2.hpp \
|
Modules/MGauge/Load.hpp \
|
||||||
Modules/MSource/SeqGamma.hpp \
|
Modules/MGauge/Random.hpp \
|
||||||
Modules/MSource/Point.hpp \
|
Modules/MGauge/StochEm.hpp \
|
||||||
Modules/MSource/Wall.hpp \
|
Modules/MGauge/Unit.hpp \
|
||||||
Modules/MSource/Laplacian.hpp \
|
Modules/MLoop/NoiseLoop.hpp \
|
||||||
Modules/MSolver/RBPrecCG.hpp \
|
|
||||||
Modules/MScalar/ChargedProp.hpp \
|
Modules/MScalar/ChargedProp.hpp \
|
||||||
Modules/MScalar/FreeProp.hpp \
|
Modules/MScalar/FreeProp.hpp \
|
||||||
Modules/MScalar/Scalar.hpp \
|
Modules/MScalar/Scalar.hpp \
|
||||||
Modules/MAction/DWF.hpp \
|
Modules/MSink/Point.hpp \
|
||||||
Modules/MAction/Wilson.hpp \
|
Modules/MSolver/RBPrecCG.hpp \
|
||||||
Modules/MGauge/StochEm.hpp \
|
Modules/MSource/Point.hpp \
|
||||||
Modules/MGauge/Unit.hpp \
|
Modules/MSource/SeqGamma.hpp \
|
||||||
Modules/MGauge/Random.hpp \
|
Modules/MSource/Wall.hpp \
|
||||||
Modules/MGauge/Load.hpp \
|
Modules/MSource/Z2.hpp
|
||||||
Modules/MSink/Point.hpp
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
#include <Grid/algorithms/approx/Chebyshev.h>
|
#include <Grid/algorithms/approx/Chebyshev.h>
|
||||||
#include <Grid/algorithms/approx/Remez.h>
|
#include <Grid/algorithms/approx/Remez.h>
|
||||||
#include <Grid/algorithms/approx/MultiShiftFunction.h>
|
#include <Grid/algorithms/approx/MultiShiftFunction.h>
|
||||||
#include <Grid/algorithms/approx/Forecast.h>
|
|
||||||
|
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradient.h>
|
#include <Grid/algorithms/iterative/ConjugateGradient.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateResidual.h>
|
#include <Grid/algorithms/iterative/ConjugateResidual.h>
|
||||||
@@ -45,16 +44,30 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
#include <Grid/algorithms/iterative/SchurRedBlack.h>
|
#include <Grid/algorithms/iterative/SchurRedBlack.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h>
|
#include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h>
|
#include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h>
|
||||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradientReliableUpdate.h>
|
// Lanczos support
|
||||||
|
//#include <Grid/algorithms/iterative/MatrixUtils.h>
|
||||||
#include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h>
|
#include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h>
|
||||||
#include <Grid/algorithms/CoarsenedMatrix.h>
|
#include <Grid/algorithms/CoarsenedMatrix.h>
|
||||||
#include <Grid/algorithms/FFT.h>
|
#include <Grid/algorithms/FFT.h>
|
||||||
|
|
||||||
|
// Eigen/lanczos
|
||||||
// EigCg
|
// EigCg
|
||||||
|
// MCR
|
||||||
// Pcg
|
// Pcg
|
||||||
|
// Multishift CG
|
||||||
// Hdcg
|
// Hdcg
|
||||||
// GCR
|
// GCR
|
||||||
// etc..
|
// etc..
|
||||||
|
|
||||||
|
// integrator/Leapfrog
|
||||||
|
// integrator/Omelyan
|
||||||
|
// integrator/ForceGradient
|
||||||
|
|
||||||
|
// montecarlo/hmc
|
||||||
|
// montecarlo/rhmc
|
||||||
|
// montecarlo/metropolis
|
||||||
|
// etc...
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ namespace Grid {
|
|||||||
// Barrel shift and collect global pencil
|
// Barrel shift and collect global pencil
|
||||||
std::vector<int> lcoor(Nd), gcoor(Nd);
|
std::vector<int> lcoor(Nd), gcoor(Nd);
|
||||||
result = source;
|
result = source;
|
||||||
int pc = processor_coor[dim];
|
|
||||||
for(int p=0;p<processors[dim];p++) {
|
for(int p=0;p<processors[dim];p++) {
|
||||||
PARALLEL_REGION
|
PARALLEL_REGION
|
||||||
{
|
{
|
||||||
@@ -241,8 +240,7 @@ namespace Grid {
|
|||||||
for(int idx=0;idx<sgrid->lSites();idx++) {
|
for(int idx=0;idx<sgrid->lSites();idx++) {
|
||||||
sgrid->LocalIndexToLocalCoor(idx,cbuf);
|
sgrid->LocalIndexToLocalCoor(idx,cbuf);
|
||||||
peekLocalSite(s,result,cbuf);
|
peekLocalSite(s,result,cbuf);
|
||||||
cbuf[dim]+=((pc+p) % processors[dim])*L;
|
cbuf[dim]+=p*L;
|
||||||
// cbuf[dim]+=p*L;
|
|
||||||
pokeLocalSite(s,pgbuf,cbuf);
|
pokeLocalSite(s,pgbuf,cbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,6 +278,7 @@ namespace Grid {
|
|||||||
flops+= flops_call*NN;
|
flops+= flops_call*NN;
|
||||||
|
|
||||||
// writing out result
|
// writing out result
|
||||||
|
int pc = processor_coor[dim];
|
||||||
PARALLEL_REGION
|
PARALLEL_REGION
|
||||||
{
|
{
|
||||||
std::vector<int> clbuf(Nd), cgbuf(Nd);
|
std::vector<int> clbuf(Nd), cgbuf(Nd);
|
||||||
|
|||||||
@@ -1,152 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/algorithms/approx/Forecast.h
|
|
||||||
|
|
||||||
Copyright (C) 2015
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 INCLUDED_FORECAST_H
|
|
||||||
#define INCLUDED_FORECAST_H
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
|
|
||||||
// Abstract base class.
|
|
||||||
// Takes a matrix (Mat), a source (phi), and a vector of Fields (chi)
|
|
||||||
// and returns a forecasted solution to the system D*psi = phi (psi).
|
|
||||||
template<class Matrix, class Field>
|
|
||||||
class Forecast
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Field operator()(Matrix &Mat, const Field& phi, const std::vector<Field>& chi) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implementation of Brower et al.'s chronological inverter (arXiv:hep-lat/9509012),
|
|
||||||
// used to forecast solutions across poles of the EOFA heatbath.
|
|
||||||
//
|
|
||||||
// Modified from CPS (cps_pp/src/util/dirac_op/d_op_base/comsrc/minresext.C)
|
|
||||||
template<class Matrix, class Field>
|
|
||||||
class ChronoForecast : public Forecast<Matrix,Field>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Field operator()(Matrix &Mat, const Field& phi, const std::vector<Field>& prev_solns)
|
|
||||||
{
|
|
||||||
int degree = prev_solns.size();
|
|
||||||
Field chi(phi); // forecasted solution
|
|
||||||
|
|
||||||
// Trivial cases
|
|
||||||
if(degree == 0){ chi = zero; return chi; }
|
|
||||||
else if(degree == 1){ return prev_solns[0]; }
|
|
||||||
|
|
||||||
RealD dot;
|
|
||||||
ComplexD xp;
|
|
||||||
Field r(phi); // residual
|
|
||||||
Field Mv(phi);
|
|
||||||
std::vector<Field> v(prev_solns); // orthonormalized previous solutions
|
|
||||||
std::vector<Field> MdagMv(degree,phi);
|
|
||||||
|
|
||||||
// Array to hold the matrix elements
|
|
||||||
std::vector<std::vector<ComplexD>> G(degree, std::vector<ComplexD>(degree));
|
|
||||||
|
|
||||||
// Solution and source vectors
|
|
||||||
std::vector<ComplexD> a(degree);
|
|
||||||
std::vector<ComplexD> b(degree);
|
|
||||||
|
|
||||||
// Orthonormalize the vector basis
|
|
||||||
for(int i=0; i<degree; i++){
|
|
||||||
v[i] *= 1.0/std::sqrt(norm2(v[i]));
|
|
||||||
for(int j=i+1; j<degree; j++){ v[j] -= innerProduct(v[i],v[j]) * v[i]; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform sparse matrix multiplication and construct rhs
|
|
||||||
for(int i=0; i<degree; i++){
|
|
||||||
b[i] = innerProduct(v[i],phi);
|
|
||||||
Mat.M(v[i],Mv);
|
|
||||||
Mat.Mdag(Mv,MdagMv[i]);
|
|
||||||
G[i][i] = innerProduct(v[i],MdagMv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the matrix
|
|
||||||
for(int j=0; j<degree; j++){
|
|
||||||
for(int k=j+1; k<degree; k++){
|
|
||||||
G[j][k] = innerProduct(v[j],MdagMv[k]);
|
|
||||||
G[k][j] = std::conj(G[j][k]);
|
|
||||||
}}
|
|
||||||
|
|
||||||
// Gauss-Jordan elimination with partial pivoting
|
|
||||||
for(int i=0; i<degree; i++){
|
|
||||||
|
|
||||||
// Perform partial pivoting
|
|
||||||
int k = i;
|
|
||||||
for(int j=i+1; j<degree; j++){ if(std::abs(G[j][j]) > std::abs(G[k][k])){ k = j; } }
|
|
||||||
if(k != i){
|
|
||||||
xp = b[k];
|
|
||||||
b[k] = b[i];
|
|
||||||
b[i] = xp;
|
|
||||||
for(int j=0; j<degree; j++){
|
|
||||||
xp = G[k][j];
|
|
||||||
G[k][j] = G[i][j];
|
|
||||||
G[i][j] = xp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert matrix to upper triangular form
|
|
||||||
for(int j=i+1; j<degree; j++){
|
|
||||||
xp = G[j][i]/G[i][i];
|
|
||||||
b[j] -= xp * b[i];
|
|
||||||
for(int k=0; k<degree; k++){ G[j][k] -= xp*G[i][k]; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use Gaussian elimination to solve equations and calculate initial guess
|
|
||||||
chi = zero;
|
|
||||||
r = phi;
|
|
||||||
for(int i=degree-1; i>=0; i--){
|
|
||||||
a[i] = 0.0;
|
|
||||||
for(int j=i+1; j<degree; j++){ a[i] += G[i][j] * a[j]; }
|
|
||||||
a[i] = (b[i]-a[i])/G[i][i];
|
|
||||||
chi += a[i]*v[i];
|
|
||||||
r -= a[i]*MdagMv[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD true_r(0.0);
|
|
||||||
ComplexD tmp;
|
|
||||||
for(int i=0; i<degree; i++){
|
|
||||||
tmp = -b[i];
|
|
||||||
for(int j=0; j<degree; j++){ tmp += G[i][j]*a[j]; }
|
|
||||||
tmp = std::conj(tmp)*tmp;
|
|
||||||
true_r += std::sqrt(tmp.real());
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD error = std::sqrt(norm2(r)/norm2(phi));
|
|
||||||
std::cout << GridLogMessage << "ChronoForecast: |res|/|src| = " << error << std::endl;
|
|
||||||
|
|
||||||
return chi;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -87,22 +87,15 @@ void ThinQRfact (Eigen::MatrixXcd &m_rr,
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
sliceInnerProductMatrix(m_rr,R,R,Orthog);
|
sliceInnerProductMatrix(m_rr,R,R,Orthog);
|
||||||
|
|
||||||
// Force manifest hermitian to avoid rounding related
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
m_rr = 0.5*(m_rr+m_rr.adjoint());
|
// Cholesky from Eigen
|
||||||
|
// There exists a ldlt that is documented as more stable
|
||||||
#if 0
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
std::cout << " Calling Cholesky ldlt on m_rr " << m_rr <<std::endl;
|
|
||||||
Eigen::MatrixXcd L_ldlt = m_rr.ldlt().matrixL();
|
|
||||||
std::cout << " Called Cholesky ldlt on m_rr " << L_ldlt <<std::endl;
|
|
||||||
auto D_ldlt = m_rr.ldlt().vectorD();
|
|
||||||
std::cout << " Called Cholesky ldlt on m_rr " << D_ldlt <<std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// std::cout << " Calling Cholesky llt on m_rr " <<std::endl;
|
|
||||||
Eigen::MatrixXcd L = m_rr.llt().matrixL();
|
Eigen::MatrixXcd L = m_rr.llt().matrixL();
|
||||||
// std::cout << " Called Cholesky llt on m_rr " << L <<std::endl;
|
|
||||||
C = L.adjoint();
|
C = L.adjoint();
|
||||||
Cinv = C.inverse();
|
Cinv = C.inverse();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Q = R C^{-1}
|
// Q = R C^{-1}
|
||||||
//
|
//
|
||||||
@@ -110,6 +103,7 @@ void ThinQRfact (Eigen::MatrixXcd &m_rr,
|
|||||||
//
|
//
|
||||||
// NB maddMatrix conventions are Right multiplication X[j] a[j,i] already
|
// NB maddMatrix conventions are Right multiplication X[j] a[j,i] already
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// FIXME:: make a sliceMulMatrix to avoid zero vector
|
||||||
sliceMulMatrix(Q,Cinv,R,Orthog);
|
sliceMulMatrix(Q,Cinv,R,Orthog);
|
||||||
}
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ class ConjugateGradient : public OperatorFunction<Field> {
|
|||||||
MaxIterations(maxit),
|
MaxIterations(maxit),
|
||||||
ErrorOnNoConverge(err_on_no_conv){};
|
ErrorOnNoConverge(err_on_no_conv){};
|
||||||
|
|
||||||
void operator()(LinearOperatorBase<Field> &Linop, const Field &src, Field &psi) {
|
void operator()(LinearOperatorBase<Field> &Linop, const Field &src,
|
||||||
|
Field &psi) {
|
||||||
psi.checkerboard = src.checkerboard;
|
psi.checkerboard = src.checkerboard;
|
||||||
conformable(psi, src);
|
conformable(psi, src);
|
||||||
|
|
||||||
|
|||||||
@@ -1,256 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/algorithms/iterative/ConjugateGradientReliableUpdate.h
|
|
||||||
|
|
||||||
Copyright (C) 2015
|
|
||||||
|
|
||||||
Author: Christopher Kelly <ckelly@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_CONJUGATE_GRADIENT_RELIABLE_UPDATE_H
|
|
||||||
#define GRID_CONJUGATE_GRADIENT_RELIABLE_UPDATE_H
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
|
|
||||||
template<class FieldD,class FieldF, typename std::enable_if< getPrecision<FieldD>::value == 2, int>::type = 0,typename std::enable_if< getPrecision<FieldF>::value == 1, int>::type = 0>
|
|
||||||
class ConjugateGradientReliableUpdate : public LinearFunction<FieldD> {
|
|
||||||
public:
|
|
||||||
bool ErrorOnNoConverge; // throw an assert when the CG fails to converge.
|
|
||||||
// Defaults true.
|
|
||||||
RealD Tolerance;
|
|
||||||
Integer MaxIterations;
|
|
||||||
Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion
|
|
||||||
Integer ReliableUpdatesPerformed;
|
|
||||||
|
|
||||||
bool DoFinalCleanup; //Final DP cleanup, defaults to true
|
|
||||||
Integer IterationsToCleanup; //Final DP cleanup step iterations
|
|
||||||
|
|
||||||
LinearOperatorBase<FieldF> &Linop_f;
|
|
||||||
LinearOperatorBase<FieldD> &Linop_d;
|
|
||||||
GridBase* SinglePrecGrid;
|
|
||||||
RealD Delta; //reliable update parameter
|
|
||||||
|
|
||||||
//Optional ability to switch to a different linear operator once the tolerance reaches a certain point. Useful for single/half -> single/single
|
|
||||||
LinearOperatorBase<FieldF> *Linop_fallback;
|
|
||||||
RealD fallback_transition_tol;
|
|
||||||
|
|
||||||
|
|
||||||
ConjugateGradientReliableUpdate(RealD tol, Integer maxit, RealD _delta, GridBase* _sp_grid, LinearOperatorBase<FieldF> &_Linop_f, LinearOperatorBase<FieldD> &_Linop_d, bool err_on_no_conv = true)
|
|
||||||
: Tolerance(tol),
|
|
||||||
MaxIterations(maxit),
|
|
||||||
Delta(_delta),
|
|
||||||
Linop_f(_Linop_f),
|
|
||||||
Linop_d(_Linop_d),
|
|
||||||
SinglePrecGrid(_sp_grid),
|
|
||||||
ErrorOnNoConverge(err_on_no_conv),
|
|
||||||
DoFinalCleanup(true),
|
|
||||||
Linop_fallback(NULL)
|
|
||||||
{};
|
|
||||||
|
|
||||||
void setFallbackLinop(LinearOperatorBase<FieldF> &_Linop_fallback, const RealD _fallback_transition_tol){
|
|
||||||
Linop_fallback = &_Linop_fallback;
|
|
||||||
fallback_transition_tol = _fallback_transition_tol;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const FieldD &src, FieldD &psi) {
|
|
||||||
LinearOperatorBase<FieldF> *Linop_f_use = &Linop_f;
|
|
||||||
bool using_fallback = false;
|
|
||||||
|
|
||||||
psi.checkerboard = src.checkerboard;
|
|
||||||
conformable(psi, src);
|
|
||||||
|
|
||||||
RealD cp, c, a, d, b, ssq, qq, b_pred;
|
|
||||||
|
|
||||||
FieldD p(src);
|
|
||||||
FieldD mmp(src);
|
|
||||||
FieldD r(src);
|
|
||||||
|
|
||||||
// Initial residual computation & set up
|
|
||||||
RealD guess = norm2(psi);
|
|
||||||
assert(std::isnan(guess) == 0);
|
|
||||||
|
|
||||||
Linop_d.HermOpAndNorm(psi, mmp, d, b);
|
|
||||||
|
|
||||||
r = src - mmp;
|
|
||||||
p = r;
|
|
||||||
|
|
||||||
a = norm2(p);
|
|
||||||
cp = a;
|
|
||||||
ssq = norm2(src);
|
|
||||||
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradientReliableUpdate: guess " << guess << std::endl;
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradientReliableUpdate: src " << ssq << std::endl;
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradientReliableUpdate: mp " << d << std::endl;
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradientReliableUpdate: mmp " << b << std::endl;
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradientReliableUpdate: cp,r " << cp << std::endl;
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradientReliableUpdate: p " << a << std::endl;
|
|
||||||
|
|
||||||
RealD rsq = Tolerance * Tolerance * ssq;
|
|
||||||
|
|
||||||
// Check if guess is really REALLY good :)
|
|
||||||
if (cp <= rsq) {
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate guess was REALLY good\n";
|
|
||||||
std::cout << GridLogMessage << "\tComputed residual " << sqrt(cp / ssq)<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Single prec initialization
|
|
||||||
FieldF r_f(SinglePrecGrid);
|
|
||||||
r_f.checkerboard = r.checkerboard;
|
|
||||||
precisionChange(r_f, r);
|
|
||||||
|
|
||||||
FieldF psi_f(r_f);
|
|
||||||
psi_f = zero;
|
|
||||||
|
|
||||||
FieldF p_f(r_f);
|
|
||||||
FieldF mmp_f(r_f);
|
|
||||||
|
|
||||||
RealD MaxResidSinceLastRelUp = cp; //initial residual
|
|
||||||
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4)
|
|
||||||
<< "ConjugateGradient: k=0 residual " << cp << " target " << rsq << std::endl;
|
|
||||||
|
|
||||||
GridStopWatch LinalgTimer;
|
|
||||||
GridStopWatch MatrixTimer;
|
|
||||||
GridStopWatch SolverTimer;
|
|
||||||
|
|
||||||
SolverTimer.Start();
|
|
||||||
int k = 0;
|
|
||||||
int l = 0;
|
|
||||||
|
|
||||||
for (k = 1; k <= MaxIterations; k++) {
|
|
||||||
c = cp;
|
|
||||||
|
|
||||||
MatrixTimer.Start();
|
|
||||||
Linop_f_use->HermOpAndNorm(p_f, mmp_f, d, qq);
|
|
||||||
MatrixTimer.Stop();
|
|
||||||
|
|
||||||
LinalgTimer.Start();
|
|
||||||
|
|
||||||
a = c / d;
|
|
||||||
b_pred = a * (a * qq - d) / c;
|
|
||||||
|
|
||||||
cp = axpy_norm(r_f, -a, mmp_f, r_f);
|
|
||||||
b = cp / c;
|
|
||||||
|
|
||||||
// Fuse these loops ; should be really easy
|
|
||||||
psi_f = a * p_f + psi_f;
|
|
||||||
//p_f = p_f * b + r_f;
|
|
||||||
|
|
||||||
LinalgTimer.Stop();
|
|
||||||
|
|
||||||
std::cout << GridLogIterative << "ConjugateGradientReliableUpdate: Iteration " << k
|
|
||||||
<< " residual " << cp << " target " << rsq << std::endl;
|
|
||||||
std::cout << GridLogDebug << "a = "<< a << " b_pred = "<< b_pred << " b = "<< b << std::endl;
|
|
||||||
std::cout << GridLogDebug << "qq = "<< qq << " d = "<< d << " c = "<< c << std::endl;
|
|
||||||
|
|
||||||
if(cp > MaxResidSinceLastRelUp){
|
|
||||||
std::cout << GridLogIterative << "ConjugateGradientReliableUpdate: updating MaxResidSinceLastRelUp : " << MaxResidSinceLastRelUp << " -> " << cp << std::endl;
|
|
||||||
MaxResidSinceLastRelUp = cp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stopping condition
|
|
||||||
if (cp <= rsq) {
|
|
||||||
//Although not written in the paper, I assume that I have to add on the final solution
|
|
||||||
precisionChange(mmp, psi_f);
|
|
||||||
psi = psi + mmp;
|
|
||||||
|
|
||||||
|
|
||||||
SolverTimer.Stop();
|
|
||||||
Linop_d.HermOpAndNorm(psi, mmp, d, qq);
|
|
||||||
p = mmp - src;
|
|
||||||
|
|
||||||
RealD srcnorm = sqrt(norm2(src));
|
|
||||||
RealD resnorm = sqrt(norm2(p));
|
|
||||||
RealD true_residual = resnorm / srcnorm;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate Converged on iteration " << k << " after " << l << " reliable updates" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "\tComputed residual " << sqrt(cp / ssq)<<std::endl;
|
|
||||||
std::cout << GridLogMessage << "\tTrue residual " << true_residual<<std::endl;
|
|
||||||
std::cout << GridLogMessage << "\tTarget " << Tolerance << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Time breakdown "<<std::endl;
|
|
||||||
std::cout << GridLogMessage << "\tElapsed " << SolverTimer.Elapsed() <<std::endl;
|
|
||||||
std::cout << GridLogMessage << "\tMatrix " << MatrixTimer.Elapsed() <<std::endl;
|
|
||||||
std::cout << GridLogMessage << "\tLinalg " << LinalgTimer.Elapsed() <<std::endl;
|
|
||||||
|
|
||||||
IterationsToComplete = k;
|
|
||||||
ReliableUpdatesPerformed = l;
|
|
||||||
|
|
||||||
if(DoFinalCleanup){
|
|
||||||
//Do a final CG to cleanup
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate performing final cleanup.\n";
|
|
||||||
ConjugateGradient<FieldD> CG(Tolerance,MaxIterations);
|
|
||||||
CG.ErrorOnNoConverge = ErrorOnNoConverge;
|
|
||||||
CG(Linop_d,src,psi);
|
|
||||||
IterationsToCleanup = CG.IterationsToComplete;
|
|
||||||
}
|
|
||||||
else if (ErrorOnNoConverge) assert(true_residual / Tolerance < 10000.0);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate complete.\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if(cp < Delta * MaxResidSinceLastRelUp) { //reliable update
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate "
|
|
||||||
<< cp << "(residual) < " << Delta << "(Delta) * " << MaxResidSinceLastRelUp << "(MaxResidSinceLastRelUp) on iteration " << k << " : performing reliable update\n";
|
|
||||||
precisionChange(mmp, psi_f);
|
|
||||||
psi = psi + mmp;
|
|
||||||
|
|
||||||
Linop_d.HermOpAndNorm(psi, mmp, d, qq);
|
|
||||||
r = src - mmp;
|
|
||||||
|
|
||||||
psi_f = zero;
|
|
||||||
precisionChange(r_f, r);
|
|
||||||
cp = norm2(r);
|
|
||||||
MaxResidSinceLastRelUp = cp;
|
|
||||||
|
|
||||||
b = cp/c;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate new residual " << cp << std::endl;
|
|
||||||
|
|
||||||
l = l+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_f = p_f * b + r_f; //update search vector after reliable update appears to help convergence
|
|
||||||
|
|
||||||
if(!using_fallback && Linop_fallback != NULL && cp < fallback_transition_tol){
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate switching to fallback linear operator on iteration " << k << " at residual " << cp << std::endl;
|
|
||||||
Linop_f_use = Linop_fallback;
|
|
||||||
using_fallback = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
std::cout << GridLogMessage << "ConjugateGradientReliableUpdate did NOT converge"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
if (ErrorOnNoConverge) assert(0);
|
|
||||||
IterationsToComplete = k;
|
|
||||||
ReliableUpdatesPerformed = l;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <Grid/GridCore.h>
|
#include <Grid/GridCore.h>
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
@@ -61,37 +63,4 @@ void *PointerCache::Lookup(size_t bytes) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void check_huge_pages(void *Buf,uint64_t BYTES)
|
|
||||||
{
|
|
||||||
#ifdef __linux__
|
|
||||||
int fd = open("/proc/self/pagemap", O_RDONLY);
|
|
||||||
assert(fd >= 0);
|
|
||||||
const int page_size = 4096;
|
|
||||||
uint64_t virt_pfn = (uint64_t)Buf / page_size;
|
|
||||||
off_t offset = sizeof(uint64_t) * virt_pfn;
|
|
||||||
uint64_t npages = (BYTES + page_size-1) / page_size;
|
|
||||||
uint64_t pagedata[npages];
|
|
||||||
uint64_t ret = lseek(fd, offset, SEEK_SET);
|
|
||||||
assert(ret == offset);
|
|
||||||
ret = ::read(fd, pagedata, sizeof(uint64_t)*npages);
|
|
||||||
assert(ret == sizeof(uint64_t) * npages);
|
|
||||||
int nhugepages = npages / 512;
|
|
||||||
int n4ktotal, nnothuge;
|
|
||||||
n4ktotal = 0;
|
|
||||||
nnothuge = 0;
|
|
||||||
for (int i = 0; i < nhugepages; ++i) {
|
|
||||||
uint64_t baseaddr = (pagedata[i*512] & 0x7fffffffffffffULL) * page_size;
|
|
||||||
for (int j = 0; j < 512; ++j) {
|
|
||||||
uint64_t pageaddr = (pagedata[i*512+j] & 0x7fffffffffffffULL) * page_size;
|
|
||||||
++n4ktotal;
|
|
||||||
if (pageaddr != baseaddr + j * page_size)
|
|
||||||
++nnothuge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int rank = CartesianCommunicator::RankWorld();
|
|
||||||
printf("rank %d Allocated %d 4k pages, %d not in huge pages\n", rank, n4ktotal, nnothuge);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ namespace Grid {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void check_huge_pages(void *Buf,uint64_t BYTES);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// A lattice of something, but assume the something is SIMDized.
|
// A lattice of something, but assume the something is SIMDized.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ public:
|
|||||||
template<class object> friend class Lattice;
|
template<class object> friend class Lattice;
|
||||||
|
|
||||||
GridBase(const std::vector<int> & processor_grid) : CartesianCommunicator(processor_grid) {};
|
GridBase(const std::vector<int> & processor_grid) : CartesianCommunicator(processor_grid) {};
|
||||||
GridBase(const std::vector<int> & processor_grid,
|
|
||||||
const CartesianCommunicator &parent) : CartesianCommunicator(processor_grid,parent) {};
|
|
||||||
|
|
||||||
// Physics Grid information.
|
// Physics Grid information.
|
||||||
std::vector<int> _simd_layout;// Which dimensions get relayed out over simd lanes.
|
std::vector<int> _simd_layout;// Which dimensions get relayed out over simd lanes.
|
||||||
@@ -212,6 +210,9 @@ public:
|
|||||||
assert(lidx<lSites());
|
assert(lidx<lSites());
|
||||||
Lexicographic::CoorFromIndex(lcoor,lidx,_ldimensions);
|
Lexicographic::CoorFromIndex(lcoor,lidx,_ldimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GlobalCoorToGlobalIndex(const std::vector<int> & gcoor,int & gidx){
|
void GlobalCoorToGlobalIndex(const std::vector<int> & gcoor,int & gidx){
|
||||||
gidx=0;
|
gidx=0;
|
||||||
int mult=1;
|
int mult=1;
|
||||||
|
|||||||
@@ -61,29 +61,9 @@ public:
|
|||||||
virtual int CheckerBoardShift(int source_cb,int dim,int shift, int osite){
|
virtual int CheckerBoardShift(int source_cb,int dim,int shift, int osite){
|
||||||
return shift;
|
return shift;
|
||||||
}
|
}
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor takes a parent grid and possibly subdivides communicator.
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
GridCartesian(const std::vector<int> &dimensions,
|
|
||||||
const std::vector<int> &simd_layout,
|
|
||||||
const std::vector<int> &processor_grid,
|
|
||||||
const GridCartesian &parent) : GridBase(processor_grid,parent)
|
|
||||||
{
|
|
||||||
Init(dimensions,simd_layout,processor_grid);
|
|
||||||
}
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// Construct from comm world
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
GridCartesian(const std::vector<int> &dimensions,
|
GridCartesian(const std::vector<int> &dimensions,
|
||||||
const std::vector<int> &simd_layout,
|
const std::vector<int> &simd_layout,
|
||||||
const std::vector<int> &processor_grid) : GridBase(processor_grid)
|
const std::vector<int> &processor_grid) : GridBase(processor_grid)
|
||||||
{
|
|
||||||
Init(dimensions,simd_layout,processor_grid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init(const std::vector<int> &dimensions,
|
|
||||||
const std::vector<int> &simd_layout,
|
|
||||||
const std::vector<int> &processor_grid)
|
|
||||||
{
|
{
|
||||||
///////////////////////
|
///////////////////////
|
||||||
// Grid information
|
// Grid information
|
||||||
|
|||||||
@@ -112,57 +112,24 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
GridRedBlackCartesian(const GridBase *base) : GridRedBlackCartesian(base->_fdimensions,base->_simd_layout,base->_processors) {};
|
||||||
// Create Redblack from original grid; require full grid pointer ?
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
GridRedBlackCartesian(const GridBase *base) : GridBase(base->_processors,*base)
|
|
||||||
{
|
|
||||||
int dims = base->_ndimension;
|
|
||||||
std::vector<int> checker_dim_mask(dims,1);
|
|
||||||
int checker_dim = 0;
|
|
||||||
Init(base->_fdimensions,base->_simd_layout,base->_processors,checker_dim_mask,checker_dim);
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
GridRedBlackCartesian(const std::vector<int> &dimensions,
|
||||||
// Create redblack from original grid, with non-trivial checker dim mask
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
GridRedBlackCartesian(const GridBase *base,
|
|
||||||
const std::vector<int> &checker_dim_mask,
|
|
||||||
int checker_dim
|
|
||||||
) : GridBase(base->_processors,*base)
|
|
||||||
{
|
|
||||||
Init(base->_fdimensions,base->_simd_layout,base->_processors,checker_dim_mask,checker_dim) ;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Create redblack grid ;; deprecate these. Should not
|
|
||||||
// need direct creation of redblack without a full grid to base on
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
GridRedBlackCartesian(const GridBase *base,
|
|
||||||
const std::vector<int> &dimensions,
|
|
||||||
const std::vector<int> &simd_layout,
|
const std::vector<int> &simd_layout,
|
||||||
const std::vector<int> &processor_grid,
|
const std::vector<int> &processor_grid,
|
||||||
const std::vector<int> &checker_dim_mask,
|
const std::vector<int> &checker_dim_mask,
|
||||||
int checker_dim
|
int checker_dim
|
||||||
) : GridBase(processor_grid,*base)
|
) : GridBase(processor_grid)
|
||||||
{
|
{
|
||||||
Init(dimensions,simd_layout,processor_grid,checker_dim_mask,checker_dim);
|
Init(dimensions,simd_layout,processor_grid,checker_dim_mask,checker_dim);
|
||||||
}
|
}
|
||||||
|
GridRedBlackCartesian(const std::vector<int> &dimensions,
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Create redblack grid
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
GridRedBlackCartesian(const GridBase *base,
|
|
||||||
const std::vector<int> &dimensions,
|
|
||||||
const std::vector<int> &simd_layout,
|
const std::vector<int> &simd_layout,
|
||||||
const std::vector<int> &processor_grid) : GridBase(processor_grid,*base)
|
const std::vector<int> &processor_grid) : GridBase(processor_grid)
|
||||||
{
|
{
|
||||||
std::vector<int> checker_dim_mask(dimensions.size(),1);
|
std::vector<int> checker_dim_mask(dimensions.size(),1);
|
||||||
int checker_dim = 0;
|
Init(dimensions,simd_layout,processor_grid,checker_dim_mask,0);
|
||||||
Init(dimensions,simd_layout,processor_grid,checker_dim_mask,checker_dim);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void Init(const std::vector<int> &dimensions,
|
void Init(const std::vector<int> &dimensions,
|
||||||
const std::vector<int> &simd_layout,
|
const std::vector<int> &simd_layout,
|
||||||
const std::vector<int> &processor_grid,
|
const std::vector<int> &processor_grid,
|
||||||
|
|||||||
@@ -96,105 +96,6 @@ void CartesianCommunicator::GlobalSumVector(ComplexD *c,int N)
|
|||||||
GlobalSumVector((double *)c,2*N);
|
GlobalSumVector((double *)c,2*N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined( GRID_COMMS_MPI) || defined (GRID_COMMS_MPIT)
|
|
||||||
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors,const CartesianCommunicator &parent)
|
|
||||||
{
|
|
||||||
_ndimension = processors.size();
|
|
||||||
assert(_ndimension = parent._ndimension);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// split the communicator
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
int Nparent;
|
|
||||||
MPI_Comm_size(parent.communicator,&Nparent);
|
|
||||||
|
|
||||||
int childsize=1;
|
|
||||||
for(int d=0;d<processors.size();d++) {
|
|
||||||
childsize *= processors[d];
|
|
||||||
}
|
|
||||||
int Nchild = Nparent/childsize;
|
|
||||||
assert (childsize * Nchild == Nparent);
|
|
||||||
|
|
||||||
int prank; MPI_Comm_rank(parent.communicator,&prank);
|
|
||||||
int crank = prank % childsize;
|
|
||||||
int ccomm = prank / childsize;
|
|
||||||
|
|
||||||
MPI_Comm comm_split;
|
|
||||||
if ( Nchild > 1 ) {
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<<"Child communicator of "<< std::hex << parent.communicator << std::dec<<std::endl;
|
|
||||||
std::cout << GridLogMessage<<" parent grid["<< parent._ndimension<<"] ";
|
|
||||||
for(int d=0;d<parent._processors.size();d++) std::cout << parent._processors[d] << " ";
|
|
||||||
std::cout<<std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<<" child grid["<< _ndimension <<"] ";
|
|
||||||
for(int d=0;d<processors.size();d++) std::cout << processors[d] << " ";
|
|
||||||
std::cout<<std::endl;
|
|
||||||
|
|
||||||
int ierr= MPI_Comm_split(parent.communicator, ccomm,crank,&comm_split);
|
|
||||||
assert(ierr==0);
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Declare victory
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::cout << GridLogMessage<<"Divided communicator "<< parent._Nprocessors<<" into "
|
|
||||||
<<Nchild <<" communicators with " << childsize << " ranks"<<std::endl;
|
|
||||||
} else {
|
|
||||||
comm_split=parent.communicator;
|
|
||||||
// std::cout << "Passed parental communicator to a new communicator" <<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Set up from the new split communicator
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
InitFromMPICommunicator(processors,comm_split);
|
|
||||||
}
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Take an MPI_Comm and self assemble
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void CartesianCommunicator::InitFromMPICommunicator(const std::vector<int> &processors, MPI_Comm communicator_base)
|
|
||||||
{
|
|
||||||
// if ( communicator_base != communicator_world ) {
|
|
||||||
// std::cout << "Cartesian communicator created with a non-world communicator"<<std::endl;
|
|
||||||
// }
|
|
||||||
_ndimension = processors.size();
|
|
||||||
_processor_coor.resize(_ndimension);
|
|
||||||
|
|
||||||
/////////////////////////////////
|
|
||||||
// Count the requested nodes
|
|
||||||
/////////////////////////////////
|
|
||||||
_Nprocessors=1;
|
|
||||||
_processors = processors;
|
|
||||||
for(int i=0;i<_ndimension;i++){
|
|
||||||
_Nprocessors*=_processors[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> periodic(_ndimension,1);
|
|
||||||
MPI_Cart_create(communicator_base, _ndimension,&_processors[0],&periodic[0],1,&communicator);
|
|
||||||
MPI_Comm_rank(communicator,&_processor);
|
|
||||||
MPI_Cart_coords(communicator,_processor,_ndimension,&_processor_coor[0]);
|
|
||||||
|
|
||||||
int Size;
|
|
||||||
MPI_Comm_size(communicator,&Size);
|
|
||||||
|
|
||||||
#ifdef GRID_COMMS_MPIT
|
|
||||||
communicator_halo.resize (2*_ndimension);
|
|
||||||
for(int i=0;i<_ndimension*2;i++){
|
|
||||||
MPI_Comm_dup(communicator,&communicator_halo[i]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(Size==_Nprocessors);
|
|
||||||
}
|
|
||||||
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
|
||||||
{
|
|
||||||
InitFromMPICommunicator(processors,communicator_world);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined( GRID_COMMS_MPI3)
|
#if !defined( GRID_COMMS_MPI3)
|
||||||
|
|
||||||
int CartesianCommunicator::NodeCount(void) { return ProcessorCount();};
|
int CartesianCommunicator::NodeCount(void) { return ProcessorCount();};
|
||||||
@@ -246,13 +147,8 @@ void *CartesianCommunicator::ShmBufferTranslate(int rank,void * local_p) {
|
|||||||
}
|
}
|
||||||
void CartesianCommunicator::ShmInitGeneric(void){
|
void CartesianCommunicator::ShmInitGeneric(void){
|
||||||
#if 1
|
#if 1
|
||||||
int mmap_flag =0;
|
|
||||||
#ifdef MAP_ANONYMOUS
|
int mmap_flag = MAP_SHARED | MAP_ANONYMOUS;
|
||||||
mmap_flag = mmap_flag| MAP_SHARED | MAP_ANONYMOUS;
|
|
||||||
#endif
|
|
||||||
#ifdef MAP_ANON
|
|
||||||
mmap_flag = mmap_flag| MAP_SHARED | MAP_ANON;
|
|
||||||
#endif
|
|
||||||
#ifdef MAP_HUGETLB
|
#ifdef MAP_HUGETLB
|
||||||
if ( Hugepages ) mmap_flag |= MAP_HUGETLB;
|
if ( Hugepages ) mmap_flag |= MAP_HUGETLB;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ class CartesianCommunicator {
|
|||||||
std::vector<MPI_Comm> communicator_halo;
|
std::vector<MPI_Comm> communicator_halo;
|
||||||
|
|
||||||
typedef MPI_Request CommsRequest_t;
|
typedef MPI_Request CommsRequest_t;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
typedef int CommsRequest_t;
|
typedef int CommsRequest_t;
|
||||||
#endif
|
#endif
|
||||||
@@ -150,22 +149,10 @@ class CartesianCommunicator {
|
|||||||
static void Init(int *argc, char ***argv);
|
static void Init(int *argc, char ***argv);
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
// Constructors to sub-divide a parent communicator
|
// Constructor of any given grid
|
||||||
// and default to comm world
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
CartesianCommunicator(const std::vector<int> &processors,const CartesianCommunicator &parent);
|
|
||||||
CartesianCommunicator(const std::vector<int> &pdimensions_in);
|
CartesianCommunicator(const std::vector<int> &pdimensions_in);
|
||||||
|
|
||||||
private:
|
|
||||||
#if defined (GRID_COMMS_MPI) || defined (GRID_COMMS_MPIT)
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
// Private initialise from an MPI communicator
|
|
||||||
// Can use after an MPI_Comm_split, but hidden from user so private
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
void InitFromMPICommunicator(const std::vector<int> &processors, MPI_Comm communicator_base);
|
|
||||||
#endif
|
|
||||||
public:
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Wraps MPI_Cart routines, or implements equivalent on other impls
|
// Wraps MPI_Cart routines, or implements equivalent on other impls
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -52,6 +52,29 @@ void CartesianCommunicator::Init(int *argc, char ***argv) {
|
|||||||
MPI_Comm_dup (MPI_COMM_WORLD,&communicator_world);
|
MPI_Comm_dup (MPI_COMM_WORLD,&communicator_world);
|
||||||
ShmInitGeneric();
|
ShmInitGeneric();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
||||||
|
{
|
||||||
|
_ndimension = processors.size();
|
||||||
|
std::vector<int> periodic(_ndimension,1);
|
||||||
|
|
||||||
|
_Nprocessors=1;
|
||||||
|
_processors = processors;
|
||||||
|
_processor_coor.resize(_ndimension);
|
||||||
|
|
||||||
|
MPI_Cart_create(communicator_world, _ndimension,&_processors[0],&periodic[0],1,&communicator);
|
||||||
|
MPI_Comm_rank(communicator,&_processor);
|
||||||
|
MPI_Cart_coords(communicator,_processor,_ndimension,&_processor_coor[0]);
|
||||||
|
|
||||||
|
for(int i=0;i<_ndimension;i++){
|
||||||
|
_Nprocessors*=_processors[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int Size;
|
||||||
|
MPI_Comm_size(communicator,&Size);
|
||||||
|
|
||||||
|
assert(Size==_Nprocessors);
|
||||||
|
}
|
||||||
void CartesianCommunicator::GlobalSum(uint32_t &u){
|
void CartesianCommunicator::GlobalSum(uint32_t &u){
|
||||||
int ierr=MPI_Allreduce(MPI_IN_PLACE,&u,1,MPI_UINT32_T,MPI_SUM,communicator);
|
int ierr=MPI_Allreduce(MPI_IN_PLACE,&u,1,MPI_UINT32_T,MPI_SUM,communicator);
|
||||||
assert(ierr==0);
|
assert(ierr==0);
|
||||||
|
|||||||
@@ -450,15 +450,6 @@ void CartesianCommunicator::ProcessorCoorFromRank(int rank, std::vector<int> &c
|
|||||||
assert(lr!=-1);
|
assert(lr!=-1);
|
||||||
Lexicographic::CoorFromIndex(coor,lr,_processors);
|
Lexicographic::CoorFromIndex(coor,lr,_processors);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// Try to subdivide communicator
|
|
||||||
//////////////////////////////////
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors,const CartesianCommunicator &parent)
|
|
||||||
: CartesianCommunicator(processors)
|
|
||||||
{
|
|
||||||
std::cout << "Attempts to split MPI3 communicators will fail until implemented" <<std::endl;
|
|
||||||
}
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
||||||
{
|
{
|
||||||
int ierr;
|
int ierr;
|
||||||
|
|||||||
@@ -53,6 +53,33 @@ void CartesianCommunicator::Init(int *argc, char ***argv) {
|
|||||||
ShmInitGeneric();
|
ShmInitGeneric();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
||||||
|
{
|
||||||
|
_ndimension = processors.size();
|
||||||
|
std::vector<int> periodic(_ndimension,1);
|
||||||
|
|
||||||
|
_Nprocessors=1;
|
||||||
|
_processors = processors;
|
||||||
|
_processor_coor.resize(_ndimension);
|
||||||
|
|
||||||
|
MPI_Cart_create(communicator_world, _ndimension,&_processors[0],&periodic[0],1,&communicator);
|
||||||
|
MPI_Comm_rank(communicator,&_processor);
|
||||||
|
MPI_Cart_coords(communicator,_processor,_ndimension,&_processor_coor[0]);
|
||||||
|
|
||||||
|
for(int i=0;i<_ndimension;i++){
|
||||||
|
_Nprocessors*=_processors[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
communicator_halo.resize (2*_ndimension);
|
||||||
|
for(int i=0;i<_ndimension*2;i++){
|
||||||
|
MPI_Comm_dup(communicator,&communicator_halo[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Size;
|
||||||
|
MPI_Comm_size(communicator,&Size);
|
||||||
|
|
||||||
|
assert(Size==_Nprocessors);
|
||||||
|
}
|
||||||
void CartesianCommunicator::GlobalSum(uint32_t &u){
|
void CartesianCommunicator::GlobalSum(uint32_t &u){
|
||||||
int ierr=MPI_Allreduce(MPI_IN_PLACE,&u,1,MPI_UINT32_T,MPI_SUM,communicator);
|
int ierr=MPI_Allreduce(MPI_IN_PLACE,&u,1,MPI_UINT32_T,MPI_SUM,communicator);
|
||||||
assert(ierr==0);
|
assert(ierr==0);
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ void CartesianCommunicator::Init(int *argc, char *** arv)
|
|||||||
ShmInitGeneric();
|
ShmInitGeneric();
|
||||||
}
|
}
|
||||||
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors,const CartesianCommunicator &parent)
|
|
||||||
: CartesianCommunicator(processors) {}
|
|
||||||
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
||||||
{
|
{
|
||||||
_processors = processors;
|
_processors = processors;
|
||||||
|
|||||||
@@ -75,11 +75,6 @@ void CartesianCommunicator::Init(int *argc, char ***argv) {
|
|||||||
ShmInitGeneric();
|
ShmInitGeneric();
|
||||||
}
|
}
|
||||||
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors,const CartesianCommunicator &parent)
|
|
||||||
: CartesianCommunicator(processors)
|
|
||||||
{
|
|
||||||
std::cout << "Attempts to split SHMEM communicators will fail " <<std::endl;
|
|
||||||
}
|
|
||||||
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors)
|
||||||
{
|
{
|
||||||
_ndimension = processors.size();
|
_ndimension = processors.size();
|
||||||
|
|||||||
16170
lib/json/json.hpp
16170
lib/json/json.hpp
File diff suppressed because it is too large
Load Diff
@@ -544,6 +544,7 @@ static void sliceInnerProductMatrix( Eigen::MatrixXcd &mat, const Lattice<vobj>
|
|||||||
for(int i=0;i<Nblock;i++){
|
for(int i=0;i<Nblock;i++){
|
||||||
for(int j=0;j<Nblock;j++){
|
for(int j=0;j<Nblock;j++){
|
||||||
auto tmp = innerProduct(Left[i],Right[j]);
|
auto tmp = innerProduct(Left[i],Right[j]);
|
||||||
|
// vector_typeD rtmp = TensorRemove(tmp);
|
||||||
auto rtmp = TensorRemove(tmp);
|
auto rtmp = TensorRemove(tmp);
|
||||||
mat_thread(i,j) += Reduce(rtmp);
|
mat_thread(i,j) += Reduce(rtmp);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ namespace QCD {
|
|||||||
stream << "GRID_";
|
stream << "GRID_";
|
||||||
stream << ScidacWordMnemonic<stype>();
|
stream << ScidacWordMnemonic<stype>();
|
||||||
|
|
||||||
|
// std::cout << " Lorentz N/S/V/M : " << _LorentzN<<" "<<_LorentzScalar<<"/"<<_LorentzVector<<"/"<<_LorentzMatrix<<std::endl;
|
||||||
|
// std::cout << " Spin N/S/V/M : " << _SpinN <<" "<<_SpinScalar <<"/"<<_SpinVector <<"/"<<_SpinMatrix<<std::endl;
|
||||||
|
// std::cout << " Colour N/S/V/M : " << _ColourN <<" "<<_ColourScalar <<"/"<<_ColourVector <<"/"<<_ColourMatrix<<std::endl;
|
||||||
|
|
||||||
if ( _LorentzVector ) stream << "_LorentzVector"<<_LorentzN;
|
if ( _LorentzVector ) stream << "_LorentzVector"<<_LorentzN;
|
||||||
if ( _LorentzMatrix ) stream << "_LorentzMatrix"<<_LorentzN;
|
if ( _LorentzMatrix ) stream << "_LorentzMatrix"<<_LorentzN;
|
||||||
|
|
||||||
@@ -178,7 +182,7 @@ class GridLimeReader : public BinaryIO {
|
|||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
// Open the file
|
// Open the file
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
void open(const std::string &_filename)
|
void open(std::string &_filename)
|
||||||
{
|
{
|
||||||
filename= _filename;
|
filename= _filename;
|
||||||
File = fopen(filename.c_str(), "r");
|
File = fopen(filename.c_str(), "r");
|
||||||
@@ -206,33 +210,19 @@ class GridLimeReader : public BinaryIO {
|
|||||||
|
|
||||||
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
|
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
|
||||||
|
|
||||||
uint64_t file_bytes =limeReaderBytes(LimeR);
|
std::cout << GridLogMessage << limeReaderType(LimeR) <<std::endl;
|
||||||
|
|
||||||
// std::cout << GridLogMessage << limeReaderType(LimeR) << " "<< file_bytes <<" bytes "<<std::endl;
|
if ( strncmp(limeReaderType(LimeR), record_name.c_str(),strlen(record_name.c_str()) ) ) {
|
||||||
// std::cout << GridLogMessage<< " readLimeObject seeking "<< record_name <<" found record :" <<limeReaderType(LimeR) <<std::endl;
|
|
||||||
|
|
||||||
if ( !strncmp(limeReaderType(LimeR), record_name.c_str(),strlen(record_name.c_str()) ) ) {
|
|
||||||
|
|
||||||
// std::cout << GridLogMessage<< " readLimeLatticeBinaryObject matches ! " <<std::endl;
|
|
||||||
|
|
||||||
uint64_t PayloadSize = sizeof(sobj) * field._grid->_gsites;
|
|
||||||
|
|
||||||
// std::cout << "R sizeof(sobj)= " <<sizeof(sobj)<<std::endl;
|
|
||||||
// std::cout << "R Gsites " <<field._grid->_gsites<<std::endl;
|
|
||||||
// std::cout << "R Payload expected " <<PayloadSize<<std::endl;
|
|
||||||
// std::cout << "R file size " <<file_bytes <<std::endl;
|
|
||||||
|
|
||||||
assert(PayloadSize == file_bytes);// Must match or user error
|
|
||||||
|
|
||||||
off_t offset= ftell(File);
|
off_t offset= ftell(File);
|
||||||
// std::cout << " ReadLatticeObject from offset "<<offset << std::endl;
|
|
||||||
BinarySimpleMunger<sobj,sobj> munge;
|
BinarySimpleMunger<sobj,sobj> munge;
|
||||||
BinaryIO::readLatticeObject< vobj, sobj >(field, filename, munge, offset, format,nersc_csum,scidac_csuma,scidac_csumb);
|
BinaryIO::readLatticeObject< sobj, sobj >(field, filename, munge, offset, format,nersc_csum,scidac_csuma,scidac_csumb);
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
// Insist checksum is next record
|
// Insist checksum is next record
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
readLimeObject(scidacChecksum_,std::string("scidacChecksum"),std::string(SCIDAC_CHECKSUM));
|
readLimeObject(scidacChecksum_,std::string("scidacChecksum"),record_name);
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
// Verify checksums
|
// Verify checksums
|
||||||
@@ -252,19 +242,11 @@ class GridLimeReader : public BinaryIO {
|
|||||||
// should this be a do while; can we miss a first record??
|
// should this be a do while; can we miss a first record??
|
||||||
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
|
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
|
||||||
|
|
||||||
// std::cout << GridLogMessage<< " readLimeObject seeking "<< record_name <<" found record :" <<limeReaderType(LimeR) <<std::endl;
|
|
||||||
|
|
||||||
uint64_t nbytes = limeReaderBytes(LimeR);//size of this record (configuration)
|
uint64_t nbytes = limeReaderBytes(LimeR);//size of this record (configuration)
|
||||||
|
|
||||||
if ( !strncmp(limeReaderType(LimeR), record_name.c_str(),strlen(record_name.c_str()) ) ) {
|
if ( strncmp(limeReaderType(LimeR), record_name.c_str(),strlen(record_name.c_str()) ) ) {
|
||||||
|
|
||||||
// std::cout << GridLogMessage<< " readLimeObject matches ! " << record_name <<std::endl;
|
|
||||||
|
|
||||||
std::vector<char> xmlc(nbytes+1,'\0');
|
std::vector<char> xmlc(nbytes+1,'\0');
|
||||||
limeReaderReadData((void *)&xmlc[0], &nbytes, LimeR);
|
limeReaderReadData((void *)&xmlc[0], &nbytes, LimeR);
|
||||||
|
|
||||||
// std::cout << GridLogMessage<< " readLimeObject matches XML " << &xmlc[0] <<std::endl;
|
|
||||||
|
|
||||||
XmlReader RD(&xmlc[0],"");
|
XmlReader RD(&xmlc[0],"");
|
||||||
read(RD,object_name,object);
|
read(RD,object_name,object);
|
||||||
return;
|
return;
|
||||||
@@ -279,14 +261,13 @@ class GridLimeWriter : public BinaryIO {
|
|||||||
public:
|
public:
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
// FIXME: format for RNG? Now just binary out instead
|
// FIXME: format for RNG? Now just binary out instead
|
||||||
// FIXME: collective calls or not ?
|
|
||||||
// : must know if I am the I/O boss
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
FILE *File;
|
FILE *File;
|
||||||
LimeWriter *LimeW;
|
LimeWriter *LimeW;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
|
||||||
void open(const std::string &_filename) {
|
void open(std::string &_filename) {
|
||||||
filename= _filename;
|
filename= _filename;
|
||||||
File = fopen(filename.c_str(), "w");
|
File = fopen(filename.c_str(), "w");
|
||||||
LimeW = limeCreateWriter(File); assert(LimeW != NULL );
|
LimeW = limeCreateWriter(File); assert(LimeW != NULL );
|
||||||
@@ -321,18 +302,14 @@ class GridLimeWriter : public BinaryIO {
|
|||||||
write(WR,object_name,object);
|
write(WR,object_name,object);
|
||||||
xmlstring = WR.XmlString();
|
xmlstring = WR.XmlString();
|
||||||
}
|
}
|
||||||
// std::cout << "WriteLimeObject" << record_name <<std::endl;
|
|
||||||
uint64_t nbytes = xmlstring.size();
|
uint64_t nbytes = xmlstring.size();
|
||||||
// std::cout << " xmlstring "<< nbytes<< " " << xmlstring <<std::endl;
|
|
||||||
int err;
|
int err;
|
||||||
LimeRecordHeader *h = limeCreateHeader(MB, ME,const_cast<char *>(record_name.c_str()), nbytes);
|
LimeRecordHeader *h = limeCreateHeader(MB, ME,(char *)record_name.c_str(), nbytes); assert(h!= NULL);
|
||||||
assert(h!= NULL);
|
|
||||||
|
|
||||||
err=limeWriteRecordHeader(h, LimeW); assert(err>=0);
|
err=limeWriteRecordHeader(h, LimeW); assert(err>=0);
|
||||||
err=limeWriteRecordData(&xmlstring[0], &nbytes, LimeW); assert(err>=0);
|
err=limeWriteRecordData(&xmlstring[0], &nbytes, LimeW); assert(err>=0);
|
||||||
err=limeWriterCloseRecord(LimeW); assert(err>=0);
|
err=limeWriterCloseRecord(LimeW); assert(err>=0);
|
||||||
limeDestroyHeader(h);
|
limeDestroyHeader(h);
|
||||||
// std::cout << " File offset is now"<<ftell(File) << std::endl;
|
|
||||||
}
|
}
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
// Write a generic lattice field and csum
|
// Write a generic lattice field and csum
|
||||||
@@ -349,11 +326,6 @@ class GridLimeWriter : public BinaryIO {
|
|||||||
uint64_t PayloadSize = sizeof(sobj) * field._grid->_gsites;
|
uint64_t PayloadSize = sizeof(sobj) * field._grid->_gsites;
|
||||||
createLimeRecordHeader(record_name, 0, 0, PayloadSize);
|
createLimeRecordHeader(record_name, 0, 0, PayloadSize);
|
||||||
|
|
||||||
|
|
||||||
// std::cout << "W sizeof(sobj)" <<sizeof(sobj)<<std::endl;
|
|
||||||
// std::cout << "W Gsites " <<field._grid->_gsites<<std::endl;
|
|
||||||
// std::cout << "W Payload expected " <<PayloadSize<<std::endl;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// NB: FILE and iostream are jointly writing disjoint sequences in the
|
// NB: FILE and iostream are jointly writing disjoint sequences in the
|
||||||
// the same file through different file handles (integer units).
|
// the same file through different file handles (integer units).
|
||||||
@@ -368,7 +340,6 @@ class GridLimeWriter : public BinaryIO {
|
|||||||
// v) Continue writing scidac record.
|
// v) Continue writing scidac record.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
off_t offset = ftell(File);
|
off_t offset = ftell(File);
|
||||||
// std::cout << " Writing to offset "<<offset << std::endl;
|
|
||||||
std::string format = getFormatString<vobj>();
|
std::string format = getFormatString<vobj>();
|
||||||
BinarySimpleMunger<sobj,sobj> munge;
|
BinarySimpleMunger<sobj,sobj> munge;
|
||||||
BinaryIO::writeLatticeObject<vobj,sobj>(field, filename, munge, offset, format,nersc_csum,scidac_csuma,scidac_csumb);
|
BinaryIO::writeLatticeObject<vobj,sobj>(field, filename, munge, offset, format,nersc_csum,scidac_csuma,scidac_csumb);
|
||||||
@@ -403,6 +374,8 @@ class ScidacWriter : public GridLimeWriter {
|
|||||||
template <class vobj, class userRecord>
|
template <class vobj, class userRecord>
|
||||||
void writeScidacFieldRecord(Lattice<vobj> &field,userRecord _userRecord)
|
void writeScidacFieldRecord(Lattice<vobj> &field,userRecord _userRecord)
|
||||||
{
|
{
|
||||||
|
typedef typename vobj::scalar_object sobj;
|
||||||
|
uint64_t nbytes;
|
||||||
GridBase * grid = field._grid;
|
GridBase * grid = field._grid;
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
@@ -424,66 +397,6 @@ class ScidacWriter : public GridLimeWriter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ScidacReader : public GridLimeReader {
|
|
||||||
public:
|
|
||||||
|
|
||||||
template<class SerialisableUserFile>
|
|
||||||
void readScidacFileRecord(GridBase *grid,SerialisableUserFile &_userFile)
|
|
||||||
{
|
|
||||||
scidacFile _scidacFile(grid);
|
|
||||||
readLimeObject(_scidacFile,_scidacFile.SerialisableClassName(),std::string(SCIDAC_PRIVATE_FILE_XML));
|
|
||||||
readLimeObject(_userFile,_userFile.SerialisableClassName(),std::string(SCIDAC_FILE_XML));
|
|
||||||
}
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
// Write generic lattice field in scidac format
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
template <class vobj, class userRecord>
|
|
||||||
void readScidacFieldRecord(Lattice<vobj> &field,userRecord &_userRecord)
|
|
||||||
{
|
|
||||||
typedef typename vobj::scalar_object sobj;
|
|
||||||
GridBase * grid = field._grid;
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
// fill the Grid header
|
|
||||||
////////////////////////////////////////
|
|
||||||
FieldMetaData header;
|
|
||||||
scidacRecord _scidacRecord;
|
|
||||||
scidacFile _scidacFile;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Fill the Lime file record by record
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
readLimeObject(header ,std::string("FieldMetaData"),std::string(GRID_FORMAT)); // Open message
|
|
||||||
readLimeObject(_userRecord,_userRecord.SerialisableClassName(),std::string(SCIDAC_RECORD_XML));
|
|
||||||
readLimeObject(_scidacRecord,_scidacRecord.SerialisableClassName(),std::string(SCIDAC_PRIVATE_RECORD_XML));
|
|
||||||
readLimeLatticeBinaryObject(field,std::string(ILDG_BINARY_DATA));
|
|
||||||
}
|
|
||||||
void skipPastBinaryRecord(void) {
|
|
||||||
std::string rec_name(ILDG_BINARY_DATA);
|
|
||||||
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
|
|
||||||
if ( !strncmp(limeReaderType(LimeR), rec_name.c_str(),strlen(rec_name.c_str()) ) ) {
|
|
||||||
skipPastObjectRecord(std::string(SCIDAC_CHECKSUM));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void skipPastObjectRecord(std::string rec_name) {
|
|
||||||
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
|
|
||||||
if ( !strncmp(limeReaderType(LimeR), rec_name.c_str(),strlen(rec_name.c_str()) ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void skipScidacFieldRecord() {
|
|
||||||
skipPastObjectRecord(std::string(GRID_FORMAT));
|
|
||||||
skipPastObjectRecord(std::string(SCIDAC_RECORD_XML));
|
|
||||||
skipPastObjectRecord(std::string(SCIDAC_PRIVATE_RECORD_XML));
|
|
||||||
skipPastBinaryRecord();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class IldgWriter : public ScidacWriter {
|
class IldgWriter : public ScidacWriter {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -512,6 +425,8 @@ class IldgWriter : public ScidacWriter {
|
|||||||
typedef iLorentzColourMatrix<vsimd> vobj;
|
typedef iLorentzColourMatrix<vsimd> vobj;
|
||||||
typedef typename vobj::scalar_object sobj;
|
typedef typename vobj::scalar_object sobj;
|
||||||
|
|
||||||
|
uint64_t nbytes;
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// fill the Grid header
|
// fill the Grid header
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|||||||
@@ -64,11 +64,6 @@ namespace Grid {
|
|||||||
// file compatability, so should be correct to assume the undocumented but defacto file structure.
|
// file compatability, so should be correct to assume the undocumented but defacto file structure.
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct emptyUserRecord : Serializable {
|
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(emptyUserRecord,int,dummy);
|
|
||||||
emptyUserRecord() { dummy=0; };
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// Scidac private file xml
|
// Scidac private file xml
|
||||||
// <?xml version="1.0" encoding="UTF-8"?><scidacFile><version>1.1</version><spacetime>4</spacetime><dims>16 16 16 32 </dims><volfmt>0</volfmt></scidacFile>
|
// <?xml version="1.0" encoding="UTF-8"?><scidacFile><version>1.1</version><spacetime>4</spacetime><dims>16 16 16 32 </dims><volfmt>0</volfmt></scidacFile>
|
||||||
|
|||||||
@@ -85,9 +85,6 @@ namespace Grid {
|
|||||||
nd=4;
|
nd=4;
|
||||||
dimension.resize(4);
|
dimension.resize(4);
|
||||||
boundary.resize(4);
|
boundary.resize(4);
|
||||||
scidac_checksuma=0;
|
|
||||||
scidac_checksumb=0;
|
|
||||||
checksum=0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -107,7 +104,6 @@ namespace Grid {
|
|||||||
header.nd = nd;
|
header.nd = nd;
|
||||||
header.dimension.resize(nd);
|
header.dimension.resize(nd);
|
||||||
header.boundary.resize(nd);
|
header.boundary.resize(nd);
|
||||||
header.data_start = 0;
|
|
||||||
for(int d=0;d<nd;d++) {
|
for(int d=0;d<nd;d++) {
|
||||||
header.dimension[d] = grid->_fdimensions[d];
|
header.dimension[d] = grid->_fdimensions[d];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,4 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
#include <Grid/qcd/action/pseudofermion/PseudoFermion.h>
|
#include <Grid/qcd/action/pseudofermion/PseudoFermion.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// Laplacian on fermion fields
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <Grid/qcd/utils/CovariantLaplacian.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ directory
|
|||||||
// Utility functions
|
// Utility functions
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
#include <Grid/qcd/utils/Metric.h>
|
#include <Grid/qcd/utils/Metric.h>
|
||||||
#include <Grid/qcd/utils/CovariantAdjointLaplacian.h>
|
#include <Grid/qcd/utils/CovariantLaplacian.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/AbstractEOFAFermion.h
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_ABSTRACT_EOFA_FERMION_H
|
|
||||||
#define GRID_QCD_ABSTRACT_EOFA_FERMION_H
|
|
||||||
|
|
||||||
#include <Grid/qcd/action/fermion/CayleyFermion5D.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
// DJM: Abstract base class for EOFA fermion types.
|
|
||||||
// Defines layout of additional EOFA-specific parameters and operators.
|
|
||||||
// Use to construct EOFA pseudofermion actions that are agnostic to
|
|
||||||
// Shamir / Mobius / etc., and ensure that no one can construct EOFA
|
|
||||||
// pseudofermion action with non-EOFA fermion type.
|
|
||||||
template<class Impl>
|
|
||||||
class AbstractEOFAFermion : public CayleyFermion5D<Impl> {
|
|
||||||
public:
|
|
||||||
INHERIT_IMPL_TYPES(Impl);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Fermion operator: D(mq1) + shift*\gamma_{5}*R_{5}*\Delta_{\pm}(mq2,mq3)*P_{\pm}
|
|
||||||
RealD mq1;
|
|
||||||
RealD mq2;
|
|
||||||
RealD mq3;
|
|
||||||
RealD shift;
|
|
||||||
int pm;
|
|
||||||
|
|
||||||
RealD alpha; // Mobius scale
|
|
||||||
RealD k; // EOFA normalization constant
|
|
||||||
|
|
||||||
virtual void Instantiatable(void) = 0;
|
|
||||||
|
|
||||||
// EOFA-specific operations
|
|
||||||
// Force user to implement in derived classes
|
|
||||||
virtual void Omega (const FermionField& in, FermionField& out, int sign, int dag) = 0;
|
|
||||||
virtual void Dtilde (const FermionField& in, FermionField& out) = 0;
|
|
||||||
virtual void DtildeInv(const FermionField& in, FermionField& out) = 0;
|
|
||||||
|
|
||||||
// Implement derivatives in base class:
|
|
||||||
// for EOFA both DWF and Mobius just need d(Dw)/dU
|
|
||||||
virtual void MDeriv(GaugeField& mat, const FermionField& U, const FermionField& V, int dag){
|
|
||||||
this->DhopDeriv(mat, U, V, dag);
|
|
||||||
};
|
|
||||||
virtual void MoeDeriv(GaugeField& mat, const FermionField& U, const FermionField& V, int dag){
|
|
||||||
this->DhopDerivOE(mat, U, V, dag);
|
|
||||||
};
|
|
||||||
virtual void MeoDeriv(GaugeField& mat, const FermionField& U, const FermionField& V, int dag){
|
|
||||||
this->DhopDerivEO(mat, U, V, dag);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Recompute 5D coefficients for different value of shift constant
|
|
||||||
// (needed for heatbath loop over poles)
|
|
||||||
virtual void RefreshShiftCoefficients(RealD new_shift) = 0;
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
AbstractEOFAFermion(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())
|
|
||||||
: CayleyFermion5D<Impl>(_Umu, FiveDimGrid, FiveDimRedBlackGrid, FourDimGrid, FourDimRedBlackGrid,
|
|
||||||
_mq1, _M5, p), mq1(_mq1), mq2(_mq2), mq3(_mq3), shift(_shift), pm(_pm)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
this->alpha = _b + _c;
|
|
||||||
this->k = this->alpha * (_mq3-_mq2) * std::pow(this->alpha+1.0,2*Ls) /
|
|
||||||
( std::pow(this->alpha+1.0,Ls) + _mq2*std::pow(this->alpha-1.0,Ls) ) /
|
|
||||||
( std::pow(this->alpha+1.0,Ls) + _mq3*std::pow(this->alpha-1.0,Ls) );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -77,6 +77,7 @@ void CayleyFermion5D<Impl>::DminusDag(const FermionField &psi, FermionField &chi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Impl> void CayleyFermion5D<Impl>::CayleyReport(void)
|
template<class Impl> void CayleyFermion5D<Impl>::CayleyReport(void)
|
||||||
{
|
{
|
||||||
this->Report();
|
this->Report();
|
||||||
@@ -118,6 +119,7 @@ template<class Impl> void CayleyFermion5D<Impl>::CayleyZeroCounters(void)
|
|||||||
MooeeInvTime=0;
|
MooeeInvTime=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void CayleyFermion5D<Impl>::M5D (const FermionField &psi, FermionField &chi)
|
void CayleyFermion5D<Impl>::M5D (const FermionField &psi, FermionField &chi)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ namespace Grid {
|
|||||||
double MooeeInvTime;
|
double MooeeInvTime;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c);
|
void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c);
|
||||||
virtual void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
|
void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
|
||||||
virtual void SetCoefficientsInternal(RealD zolo_hi,std::vector<Coeff_t> & gamma,RealD b,RealD c);
|
void SetCoefficientsInternal(RealD zolo_hi,std::vector<Coeff_t> & gamma,RealD b,RealD c);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,438 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermion.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_Eigen_Dense.h>
|
|
||||||
#include <Grid/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/DomainWallEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
DomainWallEOFAFermion<Impl>::DomainWallEOFAFermion(
|
|
||||||
GaugeField &_Umu,
|
|
||||||
GridCartesian &FiveDimGrid,
|
|
||||||
GridRedBlackCartesian &FiveDimRedBlackGrid,
|
|
||||||
GridCartesian &FourDimGrid,
|
|
||||||
GridRedBlackCartesian &FourDimRedBlackGrid,
|
|
||||||
RealD _mq1, RealD _mq2, RealD _mq3,
|
|
||||||
RealD _shift, int _pm, RealD _M5, const ImplParams &p) :
|
|
||||||
AbstractEOFAFermion<Impl>(_Umu, FiveDimGrid, FiveDimRedBlackGrid,
|
|
||||||
FourDimGrid, FourDimRedBlackGrid, _mq1, _mq2, _mq3,
|
|
||||||
_shift, _pm, _M5, 1.0, 0.0, p)
|
|
||||||
{
|
|
||||||
RealD eps = 1.0;
|
|
||||||
Approx::zolotarev_data *zdata = Approx::higham(eps,this->Ls);
|
|
||||||
assert(zdata->n == this->Ls);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "DomainWallEOFAFermion with Ls=" << this->Ls << std::endl;
|
|
||||||
this->SetCoefficientsTanh(zdata, 1.0, 0.0);
|
|
||||||
|
|
||||||
Approx::zolotarev_free(zdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Additional EOFA operators only called outside the inverter.
|
|
||||||
Since speed is not essential, simple axpby-style
|
|
||||||
implementations should be fine.
|
|
||||||
*/
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::Omega(const FermionField& psi, FermionField& Din, int sign, int dag)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
Din = zero;
|
|
||||||
if((sign == 1) && (dag == 0)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, Ls-1, 0); }
|
|
||||||
else if((sign == -1) && (dag == 0)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, 0, 0); }
|
|
||||||
else if((sign == 1 ) && (dag == 1)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, 0, Ls-1); }
|
|
||||||
else if((sign == -1) && (dag == 1)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, 0, 0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is just the identity for DWF
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::Dtilde(const FermionField& psi, FermionField& chi){ chi = psi; }
|
|
||||||
|
|
||||||
// This is just the identity for DWF
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::DtildeInv(const FermionField& psi, FermionField& chi){ chi = psi; }
|
|
||||||
|
|
||||||
/*****************************************************************************************************/
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
RealD DomainWallEOFAFermion<Impl>::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<class Impl>
|
|
||||||
RealD DomainWallEOFAFermion<Impl>::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<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5D(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<Coeff_t> diag(Ls,1.0);
|
|
||||||
std::vector<Coeff_t> upper(Ls,-1.0); upper[Ls-1] = mq1 + shiftm;
|
|
||||||
std::vector<Coeff_t> lower(Ls,-1.0); lower[0] = mq1 + shiftp;
|
|
||||||
|
|
||||||
#if(0)
|
|
||||||
std::cout << GridLogMessage << "DomainWallEOFAFermion::M5D(FF&,FF&):" << std::endl;
|
|
||||||
for(int i=0; i<diag.size(); ++i){
|
|
||||||
std::cout << GridLogMessage << "diag[" << i << "] =" << diag[i] << std::endl;
|
|
||||||
}
|
|
||||||
for(int i=0; i<upper.size(); ++i){
|
|
||||||
std::cout << GridLogMessage << "upper[" << i << "] =" << upper[i] << std::endl;
|
|
||||||
}
|
|
||||||
for(int i=0; i<lower.size(); ++i){
|
|
||||||
std::cout << GridLogMessage << "lower[" << i << "] =" << lower[i] << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->M5D(psi, chi, chi, lower, diag, upper);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::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<Coeff_t> diag(Ls,1.0);
|
|
||||||
std::vector<Coeff_t> upper(Ls,-1.0); upper[Ls-1] = mq1 + shiftp;
|
|
||||||
std::vector<Coeff_t> lower(Ls,-1.0); lower[0] = mq1 + shiftm;
|
|
||||||
|
|
||||||
#if(0)
|
|
||||||
std::cout << GridLogMessage << "DomainWallEOFAFermion::M5Ddag(FF&,FF&):" << std::endl;
|
|
||||||
for(int i=0; i<diag.size(); ++i){
|
|
||||||
std::cout << GridLogMessage << "diag[" << i << "] =" << diag[i] << std::endl;
|
|
||||||
}
|
|
||||||
for(int i=0; i<upper.size(); ++i){
|
|
||||||
std::cout << GridLogMessage << "upper[" << i << "] =" << upper[i] << std::endl;
|
|
||||||
}
|
|
||||||
for(int i=0; i<lower.size(); ++i){
|
|
||||||
std::cout << GridLogMessage << "lower[" << i << "] =" << lower[i] << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->M5Ddag(psi, chi, chi, lower, diag, upper);
|
|
||||||
}
|
|
||||||
|
|
||||||
// half checkerboard operations
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::Mooee(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
std::vector<Coeff_t> diag = this->bee;
|
|
||||||
std::vector<Coeff_t> upper(Ls);
|
|
||||||
std::vector<Coeff_t> lower(Ls);
|
|
||||||
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
upper[s] = -this->cee[s];
|
|
||||||
lower[s] = -this->cee[s];
|
|
||||||
}
|
|
||||||
upper[Ls-1] = this->dm;
|
|
||||||
lower[0] = this->dp;
|
|
||||||
|
|
||||||
this->M5D(psi, psi, chi, lower, diag, upper);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
std::vector<Coeff_t> diag = this->bee;
|
|
||||||
std::vector<Coeff_t> upper(Ls);
|
|
||||||
std::vector<Coeff_t> lower(Ls);
|
|
||||||
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
upper[s] = -this->cee[s];
|
|
||||||
lower[s] = -this->cee[s];
|
|
||||||
}
|
|
||||||
upper[Ls-1] = this->dp;
|
|
||||||
lower[0] = this->dm;
|
|
||||||
|
|
||||||
this->M5Ddag(psi, psi, chi, lower, diag, upper);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
//Zolo
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::SetCoefficientsInternal(RealD zolo_hi, std::vector<Coeff_t>& gamma, RealD b, RealD c)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int pm = this->pm;
|
|
||||||
RealD mq1 = this->mq1;
|
|
||||||
RealD mq2 = this->mq2;
|
|
||||||
RealD mq3 = this->mq3;
|
|
||||||
RealD shift = this->shift;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// Constants for the preconditioned matrix Cayley form
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
this->bs.resize(Ls);
|
|
||||||
this->cs.resize(Ls);
|
|
||||||
this->aee.resize(Ls);
|
|
||||||
this->aeo.resize(Ls);
|
|
||||||
this->bee.resize(Ls);
|
|
||||||
this->beo.resize(Ls);
|
|
||||||
this->cee.resize(Ls);
|
|
||||||
this->ceo.resize(Ls);
|
|
||||||
|
|
||||||
for(int i=0; i<Ls; ++i){
|
|
||||||
this->bee[i] = 4.0 - this->M5 + 1.0;
|
|
||||||
this->cee[i] = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0; i<Ls; ++i){
|
|
||||||
this->aee[i] = this->cee[i];
|
|
||||||
this->bs[i] = this->beo[i] = 1.0;
|
|
||||||
this->cs[i] = this->ceo[i] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////
|
|
||||||
// EOFA shift terms
|
|
||||||
//////////////////////////////////////////
|
|
||||||
if(pm == 1){
|
|
||||||
this->dp = mq1*this->cee[0] + shift*(mq3-mq2);
|
|
||||||
this->dm = mq1*this->cee[Ls-1];
|
|
||||||
} else if(this->pm == -1) {
|
|
||||||
this->dp = mq1*this->cee[0];
|
|
||||||
this->dm = mq1*this->cee[Ls-1] - shift*(mq3-mq2);
|
|
||||||
} else {
|
|
||||||
this->dp = mq1*this->cee[0];
|
|
||||||
this->dm = mq1*this->cee[Ls-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////
|
|
||||||
// LDU decomposition of eeoo
|
|
||||||
//////////////////////////////////////////
|
|
||||||
this->dee.resize(Ls+1);
|
|
||||||
this->lee.resize(Ls);
|
|
||||||
this->leem.resize(Ls);
|
|
||||||
this->uee.resize(Ls);
|
|
||||||
this->ueem.resize(Ls);
|
|
||||||
|
|
||||||
for(int i=0; i<Ls; ++i){
|
|
||||||
|
|
||||||
if(i < Ls-1){
|
|
||||||
|
|
||||||
this->lee[i] = -this->cee[i+1]/this->bee[i]; // sub-diag entry on the ith column
|
|
||||||
|
|
||||||
this->leem[i] = this->dm/this->bee[i];
|
|
||||||
for(int j=0; j<i; j++){ this->leem[i] *= this->aee[j]/this->bee[j]; }
|
|
||||||
|
|
||||||
this->dee[i] = this->bee[i];
|
|
||||||
|
|
||||||
this->uee[i] = -this->aee[i]/this->bee[i]; // up-diag entry on the ith row
|
|
||||||
|
|
||||||
this->ueem[i] = this->dp / this->bee[0];
|
|
||||||
for(int j=1; j<=i; j++){ this->ueem[i] *= this->cee[j]/this->bee[j]; }
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
this->lee[i] = 0.0;
|
|
||||||
this->leem[i] = 0.0;
|
|
||||||
this->uee[i] = 0.0;
|
|
||||||
this->ueem[i] = 0.0;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Coeff_t delta_d = 1.0 / this->bee[0];
|
|
||||||
for(int j=1; j<Ls-1; j++){ delta_d *= this->cee[j] / this->bee[j]; }
|
|
||||||
this->dee[Ls-1] = this->bee[Ls-1] + this->cee[0] * this->dm * delta_d;
|
|
||||||
this->dee[Ls] = this->bee[Ls-1] + this->cee[Ls-1] * this->dp * delta_d;
|
|
||||||
}
|
|
||||||
|
|
||||||
int inv = 1;
|
|
||||||
this->MooeeInternalCompute(0, inv, this->MatpInv, this->MatmInv);
|
|
||||||
this->MooeeInternalCompute(1, inv, this->MatpInvDag, this->MatmInvDag);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recompute Cayley-form coefficients for different shift
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::RefreshShiftCoefficients(RealD new_shift)
|
|
||||||
{
|
|
||||||
this->shift = new_shift;
|
|
||||||
Approx::zolotarev_data *zdata = Approx::higham(1.0, this->Ls);
|
|
||||||
this->SetCoefficientsTanh(zdata, 1.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInternalCompute(int dag, int inv,
|
|
||||||
Vector<iSinglet<Simd> >& Matp, Vector<iSinglet<Simd> >& Matm)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
GridBase* grid = this->FermionRedBlackGrid();
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
|
|
||||||
if(LLs == Ls){ return; } // Not vectorised in 5th direction
|
|
||||||
|
|
||||||
Eigen::MatrixXcd Pplus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
|
||||||
Eigen::MatrixXcd Pminus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
|
||||||
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
Pplus(s,s) = this->bee[s];
|
|
||||||
Pminus(s,s) = this->bee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pminus(s,s+1) = -this->cee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pplus(s+1,s) = -this->cee[s+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
Pplus (0,Ls-1) = this->dp;
|
|
||||||
Pminus(Ls-1,0) = this->dm;
|
|
||||||
|
|
||||||
Eigen::MatrixXcd PplusMat ;
|
|
||||||
Eigen::MatrixXcd PminusMat;
|
|
||||||
|
|
||||||
#if(0)
|
|
||||||
std::cout << GridLogMessage << "Pplus:" << std::endl;
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
for(int ss=0; ss<Ls; ++ss){
|
|
||||||
std::cout << Pplus(s,ss) << "\t";
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << GridLogMessage << "Pminus:" << std::endl;
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
for(int ss=0; ss<Ls; ++ss){
|
|
||||||
std::cout << Pminus(s,ss) << "\t";
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(inv) {
|
|
||||||
PplusMat = Pplus.inverse();
|
|
||||||
PminusMat = Pminus.inverse();
|
|
||||||
} else {
|
|
||||||
PplusMat = Pplus;
|
|
||||||
PminusMat = Pminus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dag){
|
|
||||||
PplusMat.adjointInPlace();
|
|
||||||
PminusMat.adjointInPlace();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename SiteHalfSpinor::scalar_type scalar_type;
|
|
||||||
const int Nsimd = Simd::Nsimd();
|
|
||||||
Matp.resize(Ls*LLs);
|
|
||||||
Matm.resize(Ls*LLs);
|
|
||||||
|
|
||||||
for(int s2=0; s2<Ls; s2++){
|
|
||||||
for(int s1=0; s1<LLs; s1++){
|
|
||||||
int istride = LLs;
|
|
||||||
int ostride = 1;
|
|
||||||
Simd Vp;
|
|
||||||
Simd Vm;
|
|
||||||
scalar_type *sp = (scalar_type*) &Vp;
|
|
||||||
scalar_type *sm = (scalar_type*) &Vm;
|
|
||||||
for(int l=0; l<Nsimd; l++){
|
|
||||||
if(switcheroo<Coeff_t>::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(DomainWallEOFAFermion);
|
|
||||||
GparityFermOpTemplateInstantiate(DomainWallEOFAFermion);
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermion.h
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_DOMAIN_WALL_EOFA_FERMION_H
|
|
||||||
#define GRID_QCD_DOMAIN_WALL_EOFA_FERMION_H
|
|
||||||
|
|
||||||
#include <Grid/qcd/action/fermion/AbstractEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
class DomainWallEOFAFermion : public AbstractEOFAFermion<Impl>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
INHERIT_IMPL_TYPES(Impl);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Modified (0,Ls-1) and (Ls-1,0) elements of Mooee
|
|
||||||
// for red-black preconditioned Shamir EOFA
|
|
||||||
Coeff_t dm;
|
|
||||||
Coeff_t dp;
|
|
||||||
|
|
||||||
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 MooeeInvDag(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<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper);
|
|
||||||
|
|
||||||
void M5Ddag(const FermionField& psi, const FermionField& phi, FermionField& chi,
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper);
|
|
||||||
|
|
||||||
void MooeeInternal(const FermionField& in, FermionField& out, int dag, int inv);
|
|
||||||
|
|
||||||
void MooeeInternalCompute(int dag, int inv, Vector<iSinglet<Simd>>& Matp, Vector<iSinglet<Simd>>& Matm);
|
|
||||||
|
|
||||||
void MooeeInternalAsm(const FermionField& in, FermionField& out, int LLs, int site,
|
|
||||||
Vector<iSinglet<Simd>>& Matp, Vector<iSinglet<Simd>>& Matm);
|
|
||||||
|
|
||||||
void MooeeInternalZAsm(const FermionField& in, FermionField& out, int LLs, int site,
|
|
||||||
Vector<iSinglet<Simd>>& Matp, Vector<iSinglet<Simd>>& Matm);
|
|
||||||
|
|
||||||
virtual void RefreshShiftCoefficients(RealD new_shift);
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
DomainWallEOFAFermion(GaugeField& _Umu, GridCartesian& FiveDimGrid, GridRedBlackCartesian& FiveDimRedBlackGrid,
|
|
||||||
GridCartesian& FourDimGrid, GridRedBlackCartesian& FourDimRedBlackGrid,
|
|
||||||
RealD _mq1, RealD _mq2, RealD _mq3, RealD _shift, int pm,
|
|
||||||
RealD _M5, const ImplParams& p=ImplParams());
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SetCoefficientsInternal(RealD zolo_hi, std::vector<Coeff_t>& gamma, RealD b, RealD c);
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#define INSTANTIATE_DPERP_DWF_EOFA(A)\
|
|
||||||
template void DomainWallEOFAFermion<A>::M5D(const FermionField& psi, const FermionField& phi, FermionField& chi, \
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper); \
|
|
||||||
template void DomainWallEOFAFermion<A>::M5Ddag(const FermionField& psi, const FermionField& phi, FermionField& chi, \
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper); \
|
|
||||||
template void DomainWallEOFAFermion<A>::MooeeInv(const FermionField& psi, FermionField& chi); \
|
|
||||||
template void DomainWallEOFAFermion<A>::MooeeInvDag(const FermionField& psi, FermionField& chi);
|
|
||||||
|
|
||||||
#undef DOMAIN_WALL_EOFA_DPERP_DENSE
|
|
||||||
#define DOMAIN_WALL_EOFA_DPERP_CACHE
|
|
||||||
#undef DOMAIN_WALL_EOFA_DPERP_LINALG
|
|
||||||
#define DOMAIN_WALL_EOFA_DPERP_VEC
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermioncache.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/DomainWallEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
// FIXME -- make a version of these routines with site loop outermost for cache reuse.
|
|
||||||
|
|
||||||
// Pminus fowards
|
|
||||||
// Pplus backwards..
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5D(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
|
|
||||||
assert(phi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
// Flops = 6.0*(Nc*Ns) *Ls*vol
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){ // adds Ls
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
if(s==0) {
|
|
||||||
spProj5m(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+Ls-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
spProj5m(tmp, psi._odata[ss+0]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else {
|
|
||||||
spProj5m(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5Ddag(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
assert(phi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard=psi.checkerboard;
|
|
||||||
|
|
||||||
// Flops = 6.0*(Nc*Ns) *Ls*vol
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){ // adds Ls
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
spProj5p(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+Ls-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
spProj5p(tmp, psi._odata[ss+0]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else {
|
|
||||||
spProj5p(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){ // adds Ls
|
|
||||||
|
|
||||||
auto tmp1 = psi._odata[0];
|
|
||||||
auto tmp2 = psi._odata[0];
|
|
||||||
|
|
||||||
// flops = 12*2*Ls + 12*2*Ls + 3*12*Ls + 12*2*Ls = 12*Ls * (9) = 108*Ls flops
|
|
||||||
// Apply (L^{\prime})^{-1}
|
|
||||||
chi[ss] = psi[ss]; // chi[0]=psi[0]
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
spProj5p(tmp1, chi[ss+s-1]);
|
|
||||||
chi[ss+s] = psi[ss+s] - this->lee[s-1]*tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
|
|
||||||
spProj5m(tmp1, chi[ss+s]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] - this->leem[s]*tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-1} D^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[s] + 1/d chi[s]
|
|
||||||
spProj5p(tmp1, chi[ss+Ls-1]);
|
|
||||||
chi[ss+s] = (1.0/this->dee[s])*chi[ss+s] - (this->ueem[s]/this->dee[Ls])*tmp1;
|
|
||||||
}
|
|
||||||
spProj5m(tmp2, chi[ss+Ls-1]);
|
|
||||||
chi[ss+Ls-1] = (1.0/this->dee[Ls])*tmp1 + (1.0/this->dee[Ls-1])*tmp2;
|
|
||||||
|
|
||||||
// Apply U^{-1}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
spProj5m(tmp1, chi[ss+s+1]);
|
|
||||||
chi[ss+s] = chi[ss+s] - this->uee[s]*tmp1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
assert(psi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
std::vector<Coeff_t> ueec(Ls);
|
|
||||||
std::vector<Coeff_t> deec(Ls+1);
|
|
||||||
std::vector<Coeff_t> leec(Ls);
|
|
||||||
std::vector<Coeff_t> ueemc(Ls);
|
|
||||||
std::vector<Coeff_t> leemc(Ls);
|
|
||||||
|
|
||||||
for(int s=0; s<ueec.size(); s++){
|
|
||||||
ueec[s] = conjugate(this->uee[s]);
|
|
||||||
deec[s] = conjugate(this->dee[s]);
|
|
||||||
leec[s] = conjugate(this->lee[s]);
|
|
||||||
ueemc[s] = conjugate(this->ueem[s]);
|
|
||||||
leemc[s] = conjugate(this->leem[s]);
|
|
||||||
}
|
|
||||||
deec[Ls] = conjugate(this->dee[Ls]);
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){ // adds Ls
|
|
||||||
|
|
||||||
auto tmp1 = psi._odata[0];
|
|
||||||
auto tmp2 = psi._odata[0];
|
|
||||||
|
|
||||||
// Apply (U^{\prime})^{-dagger}
|
|
||||||
chi[ss] = psi[ss];
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
spProj5m(tmp1, chi[ss+s-1]);
|
|
||||||
chi[ss+s] = psi[ss+s] - ueec[s-1]*tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-\dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
spProj5p(tmp1, chi[ss+s]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] - ueemc[s]*tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-\dagger} D^{-dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
spProj5m(tmp1, chi[ss+Ls-1]);
|
|
||||||
chi[ss+s] = (1.0/deec[s])*chi[ss+s] - (leemc[s]/deec[Ls-1])*tmp1;
|
|
||||||
}
|
|
||||||
spProj5p(tmp2, chi[ss+Ls-1]);
|
|
||||||
chi[ss+Ls-1] = (1.0/deec[Ls-1])*tmp1 + (1.0/deec[Ls])*tmp2;
|
|
||||||
|
|
||||||
// Apply L^{-dagger}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
spProj5p(tmp1, chi[ss+s+1]);
|
|
||||||
chi[ss+s] = chi[ss+s] - leec[s]*tmp1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DOMAIN_WALL_EOFA_DPERP_CACHE
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplD);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplDF);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermiondense.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_Eigen_Dense.h>
|
|
||||||
#include <Grid/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/DomainWallEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dense matrix versions of routines
|
|
||||||
*/
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerYes, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerNo, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::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;
|
|
||||||
|
|
||||||
assert(Ls==LLs);
|
|
||||||
|
|
||||||
Eigen::MatrixXd Pplus = Eigen::MatrixXd::Zero(Ls,Ls);
|
|
||||||
Eigen::MatrixXd Pminus = Eigen::MatrixXd::Zero(Ls,Ls);
|
|
||||||
|
|
||||||
for(int s=0;s<Ls;s++){
|
|
||||||
Pplus(s,s) = this->bee[s];
|
|
||||||
Pminus(s,s) = this->bee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pminus(s,s+1) = -this->cee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pplus(s+1,s) = -this->cee[s+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
Pplus (0,Ls-1) = this->dp;
|
|
||||||
Pminus(Ls-1,0) = this->dm;
|
|
||||||
|
|
||||||
Eigen::MatrixXd PplusMat ;
|
|
||||||
Eigen::MatrixXd PminusMat;
|
|
||||||
|
|
||||||
if(inv) {
|
|
||||||
PplusMat = Pplus.inverse();
|
|
||||||
PminusMat = Pminus.inverse();
|
|
||||||
} else {
|
|
||||||
PplusMat = Pplus;
|
|
||||||
PminusMat = Pminus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dag){
|
|
||||||
PplusMat.adjointInPlace();
|
|
||||||
PminusMat.adjointInPlace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the non-vectorised s-direction this is simple
|
|
||||||
|
|
||||||
for(auto site=0; site<vol; site++){
|
|
||||||
|
|
||||||
SiteSpinor SiteChi;
|
|
||||||
SiteHalfSpinor SitePplus;
|
|
||||||
SiteHalfSpinor SitePminus;
|
|
||||||
|
|
||||||
for(int s1=0; s1<Ls; s1++){
|
|
||||||
SiteChi = zero;
|
|
||||||
for(int s2=0; s2<Ls; s2++){
|
|
||||||
int lex2 = s2 + Ls*site;
|
|
||||||
if(PplusMat(s1,s2) != 0.0){
|
|
||||||
spProj5p(SitePplus,psi[lex2]);
|
|
||||||
accumRecon5p(SiteChi, PplusMat(s1,s2)*SitePplus);
|
|
||||||
}
|
|
||||||
if(PminusMat(s1,s2) != 0.0){
|
|
||||||
spProj5m(SitePminus, psi[lex2]);
|
|
||||||
accumRecon5m(SiteChi, PminusMat(s1,s2)*SitePminus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chi[s1+Ls*site] = SiteChi*0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DOMAIN_WALL_EOFA_DPERP_DENSE
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplD);
|
|
||||||
|
|
||||||
template void DomainWallEOFAFermion<GparityWilsonImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<GparityWilsonImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<WilsonImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<WilsonImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZWilsonImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZWilsonImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplDF);
|
|
||||||
|
|
||||||
template void DomainWallEOFAFermion<GparityWilsonImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<GparityWilsonImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<WilsonImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<WilsonImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZWilsonImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZWilsonImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermionssp.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/DomainWallEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
// FIXME -- make a version of these routines with site loop outermost for cache reuse.
|
|
||||||
// Pminus fowards
|
|
||||||
// Pplus backwards
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5D(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pplus (chi, one, chi, lower[s], psi, s, Ls-1);
|
|
||||||
} else if (s==(Ls-1)) {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, 0);
|
|
||||||
axpby_ssp_pplus (chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pplus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5Ddag(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, Ls-1);
|
|
||||||
} else if (s==(Ls-1)) {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, 0);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
Coeff_t czero(0.0);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
// Apply (L^{\prime})^{-1}
|
|
||||||
axpby_ssp(chi, one, psi, czero, psi, 0, 0); // chi[0]=psi[0]
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
axpby_ssp_pplus(chi, one, psi, -this->lee[s-1], chi, s, s-1);// recursion Psi[s] -lee P_+ chi[s-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
|
|
||||||
axpby_ssp_pminus(chi, one, chi, -this->leem[s], chi, Ls-1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-1} D^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pplus(chi, one/this->dee[s], chi, -this->ueem[s]/this->dee[Ls], chi, s, Ls-1);
|
|
||||||
}
|
|
||||||
axpby_ssp_pminus(tmp, czero, chi, one/this->dee[Ls-1], chi, Ls-1, Ls-1);
|
|
||||||
axpby_ssp_pplus(chi, one, tmp, one/this->dee[Ls], chi, Ls-1, Ls-1);
|
|
||||||
|
|
||||||
// Apply U^{-1}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
axpby_ssp_pminus(chi, one, chi, -this->uee[s], chi, s, s+1); // chi[Ls]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
Coeff_t czero(0.0);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
// Apply (U^{\prime})^{-dagger}
|
|
||||||
axpby_ssp(chi, one, psi, czero, psi, 0, 0); // chi[0]=psi[0]
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
axpby_ssp_pminus(chi, one, psi, -conjugate(this->uee[s-1]), chi, s, s-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-\dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pplus(chi, one, chi, -conjugate(this->ueem[s]), chi, Ls-1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-\dagger} D^{-dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pminus(chi, one/conjugate(this->dee[s]), chi, -conjugate(this->leem[s]/this->dee[Ls-1]), chi, s, Ls-1);
|
|
||||||
}
|
|
||||||
axpby_ssp_pminus(tmp, czero, chi, one/conjugate(this->dee[Ls-1]), chi, Ls-1, Ls-1);
|
|
||||||
axpby_ssp_pplus(chi, one, tmp, one/conjugate(this->dee[Ls]), chi, Ls-1, Ls-1);
|
|
||||||
|
|
||||||
// Apply L^{-dagger}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
axpby_ssp_pplus(chi, one, chi, -conjugate(this->lee[s]), chi, s, s+1); // chi[Ls]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DOMAIN_WALL_EOFA_DPERP_LINALG
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplD);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(WilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(GparityWilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZWilsonImplDF);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,605 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermionvec.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/DomainWallEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dense matrix versions of routines
|
|
||||||
*/
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerYes, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerNo, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5D(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
const int nsimd = Simd::Nsimd();
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd> > u(LLs);
|
|
||||||
Vector<iSinglet<Simd> > l(LLs);
|
|
||||||
Vector<iSinglet<Simd> > 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;o<LLs;o++){ // outer
|
|
||||||
for(int i=0;i<nsimd;i++){ //inner
|
|
||||||
int s = o + i*LLs;
|
|
||||||
int ss = o*nsimd + i;
|
|
||||||
u_p[ss] = upper[s];
|
|
||||||
l_p[ss] = lower[s];
|
|
||||||
d_p[ss] = diag[s];
|
|
||||||
}}
|
|
||||||
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
assert(Nc == 3);
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); 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<LLs; v++){
|
|
||||||
|
|
||||||
int vp = (v+1)%LLs;
|
|
||||||
int vm = (v+LLs-1)%LLs;
|
|
||||||
|
|
||||||
spProj5m(hp, psi[ss+vp]);
|
|
||||||
spProj5p(hm, psi[ss+vm]);
|
|
||||||
|
|
||||||
if (vp <= v){ rotate(hp, hp, 1); }
|
|
||||||
if (vm >= 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<LLs; v++){
|
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp = (v==LLs-1) ? 0 : v+1;
|
|
||||||
int vm = (v==0) ? LLs-1 : v-1;
|
|
||||||
|
|
||||||
Simd hp_00 = psi[ss+vp]()(2)(0);
|
|
||||||
Simd hp_01 = psi[ss+vp]()(2)(1);
|
|
||||||
Simd hp_02 = psi[ss+vp]()(2)(2);
|
|
||||||
Simd hp_10 = psi[ss+vp]()(3)(0);
|
|
||||||
Simd hp_11 = psi[ss+vp]()(3)(1);
|
|
||||||
Simd hp_12 = psi[ss+vp]()(3)(2);
|
|
||||||
|
|
||||||
Simd hm_00 = psi[ss+vm]()(0)(0);
|
|
||||||
Simd hm_01 = psi[ss+vm]()(0)(1);
|
|
||||||
Simd hm_02 = psi[ss+vm]()(0)(2);
|
|
||||||
Simd hm_10 = psi[ss+vm]()(1)(0);
|
|
||||||
Simd hm_11 = psi[ss+vm]()(1)(1);
|
|
||||||
Simd hm_12 = psi[ss+vm]()(1)(2);
|
|
||||||
|
|
||||||
if(vp <= v){
|
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can force these to real arithmetic and save 2x.
|
|
||||||
Simd p_00 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00);
|
|
||||||
Simd p_01 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01);
|
|
||||||
Simd p_02 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02);
|
|
||||||
Simd p_10 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10);
|
|
||||||
Simd p_11 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11);
|
|
||||||
Simd p_12 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12);
|
|
||||||
Simd p_20 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00);
|
|
||||||
Simd p_21 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01);
|
|
||||||
Simd p_22 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02);
|
|
||||||
Simd p_30 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10);
|
|
||||||
Simd p_31 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11);
|
|
||||||
Simd p_32 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12);
|
|
||||||
|
|
||||||
vstream(chi[ss+v]()(0)(0), p_00);
|
|
||||||
vstream(chi[ss+v]()(0)(1), p_01);
|
|
||||||
vstream(chi[ss+v]()(0)(2), p_02);
|
|
||||||
vstream(chi[ss+v]()(1)(0), p_10);
|
|
||||||
vstream(chi[ss+v]()(1)(1), p_11);
|
|
||||||
vstream(chi[ss+v]()(1)(2), p_12);
|
|
||||||
vstream(chi[ss+v]()(2)(0), p_20);
|
|
||||||
vstream(chi[ss+v]()(2)(1), p_21);
|
|
||||||
vstream(chi[ss+v]()(2)(2), p_22);
|
|
||||||
vstream(chi[ss+v]()(3)(0), p_30);
|
|
||||||
vstream(chi[ss+v]()(3)(1), p_31);
|
|
||||||
vstream(chi[ss+v]()(3)(2), p_32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::M5Ddag(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
int nsimd = Simd::Nsimd();
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd> > u(LLs);
|
|
||||||
Vector<iSinglet<Simd> > l(LLs);
|
|
||||||
Vector<iSinglet<Simd> > 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; o<LLs; o++){ // outer
|
|
||||||
for(int i=0; i<nsimd; i++){ //inner
|
|
||||||
int s = o + i*LLs;
|
|
||||||
int ss = o*nsimd + i;
|
|
||||||
u_p[ss] = upper[s];
|
|
||||||
l_p[ss] = lower[s];
|
|
||||||
d_p[ss] = diag[s];
|
|
||||||
}}
|
|
||||||
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); 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<LLs; v++){
|
|
||||||
|
|
||||||
int vp = (v+1)%LLs;
|
|
||||||
int vm = (v+LLs-1)%LLs;
|
|
||||||
|
|
||||||
spProj5p(hp, psi[ss+vp]);
|
|
||||||
spProj5m(hm, psi[ss+vm]);
|
|
||||||
|
|
||||||
if(vp <= v){ rotate(hp, hp, 1); }
|
|
||||||
if(vm >= 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
for(int v=0; v<LLs; v++){
|
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp = (v == LLs-1) ? 0 : v+1;
|
|
||||||
int vm = (v == 0 ) ? LLs-1 : v-1;
|
|
||||||
|
|
||||||
Simd hp_00 = psi[ss+vp]()(0)(0);
|
|
||||||
Simd hp_01 = psi[ss+vp]()(0)(1);
|
|
||||||
Simd hp_02 = psi[ss+vp]()(0)(2);
|
|
||||||
Simd hp_10 = psi[ss+vp]()(1)(0);
|
|
||||||
Simd hp_11 = psi[ss+vp]()(1)(1);
|
|
||||||
Simd hp_12 = psi[ss+vp]()(1)(2);
|
|
||||||
|
|
||||||
Simd hm_00 = psi[ss+vm]()(2)(0);
|
|
||||||
Simd hm_01 = psi[ss+vm]()(2)(1);
|
|
||||||
Simd hm_02 = psi[ss+vm]()(2)(2);
|
|
||||||
Simd hm_10 = psi[ss+vm]()(3)(0);
|
|
||||||
Simd hm_11 = psi[ss+vm]()(3)(1);
|
|
||||||
Simd hm_12 = psi[ss+vm]()(3)(2);
|
|
||||||
|
|
||||||
if (vp <= v){
|
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Simd p_00 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00);
|
|
||||||
Simd p_01 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01);
|
|
||||||
Simd p_02 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02);
|
|
||||||
Simd p_10 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10);
|
|
||||||
Simd p_11 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11);
|
|
||||||
Simd p_12 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12);
|
|
||||||
Simd p_20 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00);
|
|
||||||
Simd p_21 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01);
|
|
||||||
Simd p_22 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02);
|
|
||||||
Simd p_30 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10);
|
|
||||||
Simd p_31 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11);
|
|
||||||
Simd p_32 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12);
|
|
||||||
|
|
||||||
vstream(chi[ss+v]()(0)(0), p_00);
|
|
||||||
vstream(chi[ss+v]()(0)(1), p_01);
|
|
||||||
vstream(chi[ss+v]()(0)(2), p_02);
|
|
||||||
vstream(chi[ss+v]()(1)(0), p_10);
|
|
||||||
vstream(chi[ss+v]()(1)(1), p_11);
|
|
||||||
vstream(chi[ss+v]()(1)(2), p_12);
|
|
||||||
vstream(chi[ss+v]()(2)(0), p_20);
|
|
||||||
vstream(chi[ss+v]()(2)(1), p_21);
|
|
||||||
vstream(chi[ss+v]()(2)(2), p_22);
|
|
||||||
vstream(chi[ss+v]()(3)(0), p_30);
|
|
||||||
vstream(chi[ss+v]()(3)(1), p_31);
|
|
||||||
vstream(chi[ss+v]()(3)(2), p_32);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef AVX512
|
|
||||||
#include<simd/Intel512common.h>
|
|
||||||
#include<simd/Intel512avx.h>
|
|
||||||
#include<simd/Intel512single.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInternalAsm(const FermionField& psi, FermionField& chi,
|
|
||||||
int LLs, int site, Vector<iSinglet<Simd> >& Matp, Vector<iSinglet<Simd> >& Matm)
|
|
||||||
{
|
|
||||||
#ifndef AVX512
|
|
||||||
{
|
|
||||||
SiteHalfSpinor BcastP;
|
|
||||||
SiteHalfSpinor BcastM;
|
|
||||||
SiteHalfSpinor SiteChiP;
|
|
||||||
SiteHalfSpinor SiteChiM;
|
|
||||||
|
|
||||||
// Ls*Ls * 2 * 12 * vol flops
|
|
||||||
for(int s1=0; s1<LLs; s1++){
|
|
||||||
|
|
||||||
for(int s2=0; s2<LLs; s2++){
|
|
||||||
for(int l=0; l < Simd::Nsimd(); l++){ // simd lane
|
|
||||||
|
|
||||||
int s = s2 + l*LLs;
|
|
||||||
int lex = s2 + LLs*site;
|
|
||||||
|
|
||||||
if( s2==0 && l==0 ){
|
|
||||||
SiteChiP=zero;
|
|
||||||
SiteChiM=zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
vbroadcast(BcastP()(sp)(co), psi[lex]()(sp)(co), l);
|
|
||||||
}}
|
|
||||||
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
vbroadcast(BcastM()(sp)(co), psi[lex]()(sp+2)(co), l);
|
|
||||||
}}
|
|
||||||
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
SiteChiP()(sp)(co) = real_madd(Matp[LLs*s+s1]()()(), BcastP()(sp)(co), SiteChiP()(sp)(co)); // 1100 us.
|
|
||||||
SiteChiM()(sp)(co) = real_madd(Matm[LLs*s+s1]()()(), BcastM()(sp)(co), SiteChiM()(sp)(co)); // each found by commenting out
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
|
|
||||||
{
|
|
||||||
int lex = s1 + LLs*site;
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
vstream(chi[lex]()(sp)(co), SiteChiP()(sp)(co));
|
|
||||||
vstream(chi[lex]()(sp+2)(co), SiteChiM()(sp)(co));
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
// pointers
|
|
||||||
// MASK_REGS;
|
|
||||||
#define Chi_00 %%zmm1
|
|
||||||
#define Chi_01 %%zmm2
|
|
||||||
#define Chi_02 %%zmm3
|
|
||||||
#define Chi_10 %%zmm4
|
|
||||||
#define Chi_11 %%zmm5
|
|
||||||
#define Chi_12 %%zmm6
|
|
||||||
#define Chi_20 %%zmm7
|
|
||||||
#define Chi_21 %%zmm8
|
|
||||||
#define Chi_22 %%zmm9
|
|
||||||
#define Chi_30 %%zmm10
|
|
||||||
#define Chi_31 %%zmm11
|
|
||||||
#define Chi_32 %%zmm12
|
|
||||||
|
|
||||||
#define BCAST0 %%zmm13
|
|
||||||
#define BCAST1 %%zmm14
|
|
||||||
#define BCAST2 %%zmm15
|
|
||||||
#define BCAST3 %%zmm16
|
|
||||||
#define BCAST4 %%zmm17
|
|
||||||
#define BCAST5 %%zmm18
|
|
||||||
#define BCAST6 %%zmm19
|
|
||||||
#define BCAST7 %%zmm20
|
|
||||||
#define BCAST8 %%zmm21
|
|
||||||
#define BCAST9 %%zmm22
|
|
||||||
#define BCAST10 %%zmm23
|
|
||||||
#define BCAST11 %%zmm24
|
|
||||||
|
|
||||||
int incr = LLs*LLs*sizeof(iSinglet<Simd>);
|
|
||||||
for(int s1=0; s1<LLs; s1++){
|
|
||||||
|
|
||||||
for(int s2=0; s2<LLs; s2++){
|
|
||||||
|
|
||||||
int lex = s2 + LLs*site;
|
|
||||||
uint64_t a0 = (uint64_t) &Matp[LLs*s2+s1]; // should be cacheable
|
|
||||||
uint64_t a1 = (uint64_t) &Matm[LLs*s2+s1];
|
|
||||||
uint64_t a2 = (uint64_t) &psi[lex];
|
|
||||||
|
|
||||||
for(int l=0; l<Simd::Nsimd(); l++){ // simd lane
|
|
||||||
if((s2+l)==0) {
|
|
||||||
asm(
|
|
||||||
VPREFETCH1(0,%2) VPREFETCH1(0,%1)
|
|
||||||
VPREFETCH1(12,%2) VPREFETCH1(13,%2)
|
|
||||||
VPREFETCH1(14,%2) VPREFETCH1(15,%2)
|
|
||||||
VBCASTCDUP(0,%2,BCAST0)
|
|
||||||
VBCASTCDUP(1,%2,BCAST1)
|
|
||||||
VBCASTCDUP(2,%2,BCAST2)
|
|
||||||
VBCASTCDUP(3,%2,BCAST3)
|
|
||||||
VBCASTCDUP(4,%2,BCAST4) VMULMEM(0,%0,BCAST0,Chi_00)
|
|
||||||
VBCASTCDUP(5,%2,BCAST5) VMULMEM(0,%0,BCAST1,Chi_01)
|
|
||||||
VBCASTCDUP(6,%2,BCAST6) VMULMEM(0,%0,BCAST2,Chi_02)
|
|
||||||
VBCASTCDUP(7,%2,BCAST7) VMULMEM(0,%0,BCAST3,Chi_10)
|
|
||||||
VBCASTCDUP(8,%2,BCAST8) VMULMEM(0,%0,BCAST4,Chi_11)
|
|
||||||
VBCASTCDUP(9,%2,BCAST9) VMULMEM(0,%0,BCAST5,Chi_12)
|
|
||||||
VBCASTCDUP(10,%2,BCAST10) VMULMEM(0,%1,BCAST6,Chi_20)
|
|
||||||
VBCASTCDUP(11,%2,BCAST11) VMULMEM(0,%1,BCAST7,Chi_21)
|
|
||||||
VMULMEM(0,%1,BCAST8,Chi_22)
|
|
||||||
VMULMEM(0,%1,BCAST9,Chi_30)
|
|
||||||
VMULMEM(0,%1,BCAST10,Chi_31)
|
|
||||||
VMULMEM(0,%1,BCAST11,Chi_32)
|
|
||||||
: : "r" (a0), "r" (a1), "r" (a2) );
|
|
||||||
} else {
|
|
||||||
asm(
|
|
||||||
VBCASTCDUP(0,%2,BCAST0) VMADDMEM(0,%0,BCAST0,Chi_00)
|
|
||||||
VBCASTCDUP(1,%2,BCAST1) VMADDMEM(0,%0,BCAST1,Chi_01)
|
|
||||||
VBCASTCDUP(2,%2,BCAST2) VMADDMEM(0,%0,BCAST2,Chi_02)
|
|
||||||
VBCASTCDUP(3,%2,BCAST3) VMADDMEM(0,%0,BCAST3,Chi_10)
|
|
||||||
VBCASTCDUP(4,%2,BCAST4) VMADDMEM(0,%0,BCAST4,Chi_11)
|
|
||||||
VBCASTCDUP(5,%2,BCAST5) VMADDMEM(0,%0,BCAST5,Chi_12)
|
|
||||||
VBCASTCDUP(6,%2,BCAST6) VMADDMEM(0,%1,BCAST6,Chi_20)
|
|
||||||
VBCASTCDUP(7,%2,BCAST7) VMADDMEM(0,%1,BCAST7,Chi_21)
|
|
||||||
VBCASTCDUP(8,%2,BCAST8) VMADDMEM(0,%1,BCAST8,Chi_22)
|
|
||||||
VBCASTCDUP(9,%2,BCAST9) VMADDMEM(0,%1,BCAST9,Chi_30)
|
|
||||||
VBCASTCDUP(10,%2,BCAST10) VMADDMEM(0,%1,BCAST10,Chi_31)
|
|
||||||
VBCASTCDUP(11,%2,BCAST11) VMADDMEM(0,%1,BCAST11,Chi_32)
|
|
||||||
: : "r" (a0), "r" (a1), "r" (a2) );
|
|
||||||
}
|
|
||||||
a0 = a0 + incr;
|
|
||||||
a1 = a1 + incr;
|
|
||||||
a2 = a2 + sizeof(Simd::scalar_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int lexa = s1+LLs*site;
|
|
||||||
asm (
|
|
||||||
VSTORE(0,%0,Chi_00) VSTORE(1 ,%0,Chi_01) VSTORE(2 ,%0,Chi_02)
|
|
||||||
VSTORE(3,%0,Chi_10) VSTORE(4 ,%0,Chi_11) VSTORE(5 ,%0,Chi_12)
|
|
||||||
VSTORE(6,%0,Chi_20) VSTORE(7 ,%0,Chi_21) VSTORE(8 ,%0,Chi_22)
|
|
||||||
VSTORE(9,%0,Chi_30) VSTORE(10,%0,Chi_31) VSTORE(11,%0,Chi_32)
|
|
||||||
: : "r" ((uint64_t)&chi[lexa]) : "memory" );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef Chi_00
|
|
||||||
#undef Chi_01
|
|
||||||
#undef Chi_02
|
|
||||||
#undef Chi_10
|
|
||||||
#undef Chi_11
|
|
||||||
#undef Chi_12
|
|
||||||
#undef Chi_20
|
|
||||||
#undef Chi_21
|
|
||||||
#undef Chi_22
|
|
||||||
#undef Chi_30
|
|
||||||
#undef Chi_31
|
|
||||||
#undef Chi_32
|
|
||||||
|
|
||||||
#undef BCAST0
|
|
||||||
#undef BCAST1
|
|
||||||
#undef BCAST2
|
|
||||||
#undef BCAST3
|
|
||||||
#undef BCAST4
|
|
||||||
#undef BCAST5
|
|
||||||
#undef BCAST6
|
|
||||||
#undef BCAST7
|
|
||||||
#undef BCAST8
|
|
||||||
#undef BCAST9
|
|
||||||
#undef BCAST10
|
|
||||||
#undef BCAST11
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// Z-mobius version
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::MooeeInternalZAsm(const FermionField& psi, FermionField& chi,
|
|
||||||
int LLs, int site, Vector<iSinglet<Simd> >& Matp, Vector<iSinglet<Simd> >& Matm)
|
|
||||||
{
|
|
||||||
std::cout << "Error: zMobius not implemented for EOFA" << std::endl;
|
|
||||||
exit(-1);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void DomainWallEOFAFermion<Impl>::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;
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd> > Matp;
|
|
||||||
Vector<iSinglet<Simd> > Matm;
|
|
||||||
Vector<iSinglet<Simd> > *_Matp;
|
|
||||||
Vector<iSinglet<Simd> > *_Matm;
|
|
||||||
|
|
||||||
// MooeeInternalCompute(dag,inv,Matp,Matm);
|
|
||||||
if(inv && dag){
|
|
||||||
_Matp = &this->MatpInvDag;
|
|
||||||
_Matm = &this->MatmInvDag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(inv && (!dag)){
|
|
||||||
_Matp = &this->MatpInv;
|
|
||||||
_Matm = &this->MatmInv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inv){
|
|
||||||
MooeeInternalCompute(dag, inv, Matp, Matm);
|
|
||||||
_Matp = &Matp;
|
|
||||||
_Matm = &Matm;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(_Matp->size() == Ls*LLs);
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
if(switcheroo<Coeff_t>::iscomplex()){
|
|
||||||
parallel_for(auto site=0; site<vol; site++){
|
|
||||||
MooeeInternalZAsm(psi, chi, LLs, site, *_Matp, *_Matm);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parallel_for(auto site=0; site<vol; site++){
|
|
||||||
MooeeInternalAsm(psi, chi, LLs, site, *_Matp, *_Matm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DOMAIN_WALL_EOFA_DPERP_VEC
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(DomainWallVec5dImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(DomainWallVec5dImplF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZDomainWallVec5dImplD);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZDomainWallVec5dImplF);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(DomainWallVec5dImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(DomainWallVec5dImplFH);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZDomainWallVec5dImplDF);
|
|
||||||
INSTANTIATE_DPERP_DWF_EOFA(ZDomainWallVec5dImplFH);
|
|
||||||
|
|
||||||
template void DomainWallEOFAFermion<DomainWallVec5dImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<DomainWallVec5dImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZDomainWallVec5dImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZDomainWallVec5dImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
template void DomainWallEOFAFermion<DomainWallVec5dImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<DomainWallVec5dImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZDomainWallVec5dImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void DomainWallEOFAFermion<ZDomainWallVec5dImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -38,8 +38,6 @@ Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|||||||
// - ContinuedFractionFermion5D.cc
|
// - ContinuedFractionFermion5D.cc
|
||||||
// - WilsonFermion.cc
|
// - WilsonFermion.cc
|
||||||
// - WilsonKernels.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
|
// 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
|
// for EVERY .cc file. This define centralises the list and restores global push of impl cases
|
||||||
@@ -57,9 +55,8 @@ Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|||||||
#include <Grid/qcd/action/fermion/ImprovedStaggeredFermion5D.h>
|
#include <Grid/qcd/action/fermion/ImprovedStaggeredFermion5D.h>
|
||||||
#include <Grid/qcd/action/fermion/CayleyFermion5D.h> // Cayley types
|
#include <Grid/qcd/action/fermion/CayleyFermion5D.h> // Cayley types
|
||||||
#include <Grid/qcd/action/fermion/DomainWallFermion.h>
|
#include <Grid/qcd/action/fermion/DomainWallFermion.h>
|
||||||
#include <Grid/qcd/action/fermion/DomainWallEOFAFermion.h>
|
#include <Grid/qcd/action/fermion/DomainWallFermion.h>
|
||||||
#include <Grid/qcd/action/fermion/MobiusFermion.h>
|
#include <Grid/qcd/action/fermion/MobiusFermion.h>
|
||||||
#include <Grid/qcd/action/fermion/MobiusEOFAFermion.h>
|
|
||||||
#include <Grid/qcd/action/fermion/ZMobiusFermion.h>
|
#include <Grid/qcd/action/fermion/ZMobiusFermion.h>
|
||||||
#include <Grid/qcd/action/fermion/SchurDiagTwoKappa.h>
|
#include <Grid/qcd/action/fermion/SchurDiagTwoKappa.h>
|
||||||
#include <Grid/qcd/action/fermion/ScaledShamirFermion.h>
|
#include <Grid/qcd/action/fermion/ScaledShamirFermion.h>
|
||||||
@@ -116,14 +113,6 @@ typedef DomainWallFermion<WilsonImplRL> DomainWallFermionRL;
|
|||||||
typedef DomainWallFermion<WilsonImplFH> DomainWallFermionFH;
|
typedef DomainWallFermion<WilsonImplFH> DomainWallFermionFH;
|
||||||
typedef DomainWallFermion<WilsonImplDF> DomainWallFermionDF;
|
typedef DomainWallFermion<WilsonImplDF> DomainWallFermionDF;
|
||||||
|
|
||||||
typedef DomainWallEOFAFermion<WilsonImplR> DomainWallEOFAFermionR;
|
|
||||||
typedef DomainWallEOFAFermion<WilsonImplF> DomainWallEOFAFermionF;
|
|
||||||
typedef DomainWallEOFAFermion<WilsonImplD> DomainWallEOFAFermionD;
|
|
||||||
|
|
||||||
typedef DomainWallEOFAFermion<WilsonImplRL> DomainWallEOFAFermionRL;
|
|
||||||
typedef DomainWallEOFAFermion<WilsonImplFH> DomainWallEOFAFermionFH;
|
|
||||||
typedef DomainWallEOFAFermion<WilsonImplDF> DomainWallEOFAFermionDF;
|
|
||||||
|
|
||||||
typedef MobiusFermion<WilsonImplR> MobiusFermionR;
|
typedef MobiusFermion<WilsonImplR> MobiusFermionR;
|
||||||
typedef MobiusFermion<WilsonImplF> MobiusFermionF;
|
typedef MobiusFermion<WilsonImplF> MobiusFermionF;
|
||||||
typedef MobiusFermion<WilsonImplD> MobiusFermionD;
|
typedef MobiusFermion<WilsonImplD> MobiusFermionD;
|
||||||
@@ -132,14 +121,6 @@ typedef MobiusFermion<WilsonImplRL> MobiusFermionRL;
|
|||||||
typedef MobiusFermion<WilsonImplFH> MobiusFermionFH;
|
typedef MobiusFermion<WilsonImplFH> MobiusFermionFH;
|
||||||
typedef MobiusFermion<WilsonImplDF> MobiusFermionDF;
|
typedef MobiusFermion<WilsonImplDF> MobiusFermionDF;
|
||||||
|
|
||||||
typedef MobiusEOFAFermion<WilsonImplR> MobiusEOFAFermionR;
|
|
||||||
typedef MobiusEOFAFermion<WilsonImplF> MobiusEOFAFermionF;
|
|
||||||
typedef MobiusEOFAFermion<WilsonImplD> MobiusEOFAFermionD;
|
|
||||||
|
|
||||||
typedef MobiusEOFAFermion<WilsonImplRL> MobiusEOFAFermionRL;
|
|
||||||
typedef MobiusEOFAFermion<WilsonImplFH> MobiusEOFAFermionFH;
|
|
||||||
typedef MobiusEOFAFermion<WilsonImplDF> MobiusEOFAFermionDF;
|
|
||||||
|
|
||||||
typedef ZMobiusFermion<ZWilsonImplR> ZMobiusFermionR;
|
typedef ZMobiusFermion<ZWilsonImplR> ZMobiusFermionR;
|
||||||
typedef ZMobiusFermion<ZWilsonImplF> ZMobiusFermionF;
|
typedef ZMobiusFermion<ZWilsonImplF> ZMobiusFermionF;
|
||||||
typedef ZMobiusFermion<ZWilsonImplD> ZMobiusFermionD;
|
typedef ZMobiusFermion<ZWilsonImplD> ZMobiusFermionD;
|
||||||
@@ -157,14 +138,6 @@ typedef DomainWallFermion<DomainWallVec5dImplRL> DomainWallFermionVec5dRL;
|
|||||||
typedef DomainWallFermion<DomainWallVec5dImplFH> DomainWallFermionVec5dFH;
|
typedef DomainWallFermion<DomainWallVec5dImplFH> DomainWallFermionVec5dFH;
|
||||||
typedef DomainWallFermion<DomainWallVec5dImplDF> DomainWallFermionVec5dDF;
|
typedef DomainWallFermion<DomainWallVec5dImplDF> DomainWallFermionVec5dDF;
|
||||||
|
|
||||||
typedef DomainWallEOFAFermion<DomainWallVec5dImplR> DomainWallEOFAFermionVec5dR;
|
|
||||||
typedef DomainWallEOFAFermion<DomainWallVec5dImplF> DomainWallEOFAFermionVec5dF;
|
|
||||||
typedef DomainWallEOFAFermion<DomainWallVec5dImplD> DomainWallEOFAFermionVec5dD;
|
|
||||||
|
|
||||||
typedef DomainWallEOFAFermion<DomainWallVec5dImplRL> DomainWallEOFAFermionVec5dRL;
|
|
||||||
typedef DomainWallEOFAFermion<DomainWallVec5dImplFH> DomainWallEOFAFermionVec5dFH;
|
|
||||||
typedef DomainWallEOFAFermion<DomainWallVec5dImplDF> DomainWallEOFAFermionVec5dDF;
|
|
||||||
|
|
||||||
typedef MobiusFermion<DomainWallVec5dImplR> MobiusFermionVec5dR;
|
typedef MobiusFermion<DomainWallVec5dImplR> MobiusFermionVec5dR;
|
||||||
typedef MobiusFermion<DomainWallVec5dImplF> MobiusFermionVec5dF;
|
typedef MobiusFermion<DomainWallVec5dImplF> MobiusFermionVec5dF;
|
||||||
typedef MobiusFermion<DomainWallVec5dImplD> MobiusFermionVec5dD;
|
typedef MobiusFermion<DomainWallVec5dImplD> MobiusFermionVec5dD;
|
||||||
@@ -173,14 +146,6 @@ typedef MobiusFermion<DomainWallVec5dImplRL> MobiusFermionVec5dRL;
|
|||||||
typedef MobiusFermion<DomainWallVec5dImplFH> MobiusFermionVec5dFH;
|
typedef MobiusFermion<DomainWallVec5dImplFH> MobiusFermionVec5dFH;
|
||||||
typedef MobiusFermion<DomainWallVec5dImplDF> MobiusFermionVec5dDF;
|
typedef MobiusFermion<DomainWallVec5dImplDF> MobiusFermionVec5dDF;
|
||||||
|
|
||||||
typedef MobiusEOFAFermion<DomainWallVec5dImplR> MobiusEOFAFermionVec5dR;
|
|
||||||
typedef MobiusEOFAFermion<DomainWallVec5dImplF> MobiusEOFAFermionVec5dF;
|
|
||||||
typedef MobiusEOFAFermion<DomainWallVec5dImplD> MobiusEOFAFermionVec5dD;
|
|
||||||
|
|
||||||
typedef MobiusEOFAFermion<DomainWallVec5dImplRL> MobiusEOFAFermionVec5dRL;
|
|
||||||
typedef MobiusEOFAFermion<DomainWallVec5dImplFH> MobiusEOFAFermionVec5dFH;
|
|
||||||
typedef MobiusEOFAFermion<DomainWallVec5dImplDF> MobiusEOFAFermionVec5dDF;
|
|
||||||
|
|
||||||
typedef ZMobiusFermion<ZDomainWallVec5dImplR> ZMobiusFermionVec5dR;
|
typedef ZMobiusFermion<ZDomainWallVec5dImplR> ZMobiusFermionVec5dR;
|
||||||
typedef ZMobiusFermion<ZDomainWallVec5dImplF> ZMobiusFermionVec5dF;
|
typedef ZMobiusFermion<ZDomainWallVec5dImplF> ZMobiusFermionVec5dF;
|
||||||
typedef ZMobiusFermion<ZDomainWallVec5dImplD> ZMobiusFermionVec5dD;
|
typedef ZMobiusFermion<ZDomainWallVec5dImplD> ZMobiusFermionVec5dD;
|
||||||
@@ -241,14 +206,6 @@ typedef DomainWallFermion<GparityWilsonImplRL> GparityDomainWallFermionRL;
|
|||||||
typedef DomainWallFermion<GparityWilsonImplFH> GparityDomainWallFermionFH;
|
typedef DomainWallFermion<GparityWilsonImplFH> GparityDomainWallFermionFH;
|
||||||
typedef DomainWallFermion<GparityWilsonImplDF> GparityDomainWallFermionDF;
|
typedef DomainWallFermion<GparityWilsonImplDF> GparityDomainWallFermionDF;
|
||||||
|
|
||||||
typedef DomainWallEOFAFermion<GparityWilsonImplR> GparityDomainWallEOFAFermionR;
|
|
||||||
typedef DomainWallEOFAFermion<GparityWilsonImplF> GparityDomainWallEOFAFermionF;
|
|
||||||
typedef DomainWallEOFAFermion<GparityWilsonImplD> GparityDomainWallEOFAFermionD;
|
|
||||||
|
|
||||||
typedef DomainWallEOFAFermion<GparityWilsonImplRL> GparityDomainWallEOFAFermionRL;
|
|
||||||
typedef DomainWallEOFAFermion<GparityWilsonImplFH> GparityDomainWallEOFAFermionFH;
|
|
||||||
typedef DomainWallEOFAFermion<GparityWilsonImplDF> GparityDomainWallEOFAFermionDF;
|
|
||||||
|
|
||||||
typedef WilsonTMFermion<GparityWilsonImplR> GparityWilsonTMFermionR;
|
typedef WilsonTMFermion<GparityWilsonImplR> GparityWilsonTMFermionR;
|
||||||
typedef WilsonTMFermion<GparityWilsonImplF> GparityWilsonTMFermionF;
|
typedef WilsonTMFermion<GparityWilsonImplF> GparityWilsonTMFermionF;
|
||||||
typedef WilsonTMFermion<GparityWilsonImplD> GparityWilsonTMFermionD;
|
typedef WilsonTMFermion<GparityWilsonImplD> GparityWilsonTMFermionD;
|
||||||
@@ -265,14 +222,6 @@ typedef MobiusFermion<GparityWilsonImplRL> GparityMobiusFermionRL;
|
|||||||
typedef MobiusFermion<GparityWilsonImplFH> GparityMobiusFermionFH;
|
typedef MobiusFermion<GparityWilsonImplFH> GparityMobiusFermionFH;
|
||||||
typedef MobiusFermion<GparityWilsonImplDF> GparityMobiusFermionDF;
|
typedef MobiusFermion<GparityWilsonImplDF> GparityMobiusFermionDF;
|
||||||
|
|
||||||
typedef MobiusEOFAFermion<GparityWilsonImplR> GparityMobiusEOFAFermionR;
|
|
||||||
typedef MobiusEOFAFermion<GparityWilsonImplF> GparityMobiusEOFAFermionF;
|
|
||||||
typedef MobiusEOFAFermion<GparityWilsonImplD> GparityMobiusEOFAFermionD;
|
|
||||||
|
|
||||||
typedef MobiusEOFAFermion<GparityWilsonImplRL> GparityMobiusEOFAFermionRL;
|
|
||||||
typedef MobiusEOFAFermion<GparityWilsonImplFH> GparityMobiusEOFAFermionFH;
|
|
||||||
typedef MobiusEOFAFermion<GparityWilsonImplDF> GparityMobiusEOFAFermionDF;
|
|
||||||
|
|
||||||
typedef ImprovedStaggeredFermion<StaggeredImplR> ImprovedStaggeredFermionR;
|
typedef ImprovedStaggeredFermion<StaggeredImplR> ImprovedStaggeredFermionR;
|
||||||
typedef ImprovedStaggeredFermion<StaggeredImplF> ImprovedStaggeredFermionF;
|
typedef ImprovedStaggeredFermion<StaggeredImplF> ImprovedStaggeredFermionF;
|
||||||
typedef ImprovedStaggeredFermion<StaggeredImplD> ImprovedStaggeredFermionD;
|
typedef ImprovedStaggeredFermion<StaggeredImplD> ImprovedStaggeredFermionD;
|
||||||
|
|||||||
@@ -538,12 +538,6 @@ class GparityWilsonImpl : public ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresent
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class ref>
|
|
||||||
inline void loadLinkElement(Simd ®, ref &memory) {
|
|
||||||
reg = memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
|
inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
|
||||||
{
|
{
|
||||||
conformable(Uds._grid,GaugeGrid);
|
conformable(Uds._grid,GaugeGrid);
|
||||||
|
|||||||
@@ -1,502 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/MobiusEOFAFermion.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_Eigen_Dense.h>
|
|
||||||
#include <Grid/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/MobiusEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
MobiusEOFAFermion<Impl>::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<Impl>(_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<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::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<Ls; ++s){
|
|
||||||
axpby_ssp(Din, 0.0, psi, 2.0*std::pow(1.0-alpha,Ls-s-1)/std::pow(1.0+alpha,Ls-s), psi, s, 0);
|
|
||||||
}
|
|
||||||
} else if((sign == -1) && (dag == 0)) { // \Omega_{-}
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
axpby_ssp(Din, 0.0, psi, 2.0*std::pow(1.0-alpha,s)/std::pow(1.0+alpha,s+1), psi, s, 0);
|
|
||||||
}
|
|
||||||
} else if((sign == 1 ) && (dag == 1)) { // \Omega_{+}^{\dagger}
|
|
||||||
for(int sp=0; sp<Ls; ++sp){
|
|
||||||
axpby_ssp(Din, 1.0, Din, 2.0*std::pow(1.0-alpha,Ls-sp-1)/std::pow(1.0+alpha,Ls-sp), psi, 0, sp);
|
|
||||||
}
|
|
||||||
} else if((sign == -1) && (dag == 1)) { // \Omega_{-}^{\dagger}
|
|
||||||
for(int sp=0; sp<Ls; ++sp){
|
|
||||||
axpby_ssp(Din, 1.0, Din, 2.0*std::pow(1.0-alpha,sp)/std::pow(1.0+alpha,sp+1), psi, 0, sp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the operator relating the usual Ddwf to TWQCD's EOFA Dirac operator (arXiv:1706.05843, Eqn. 6).
|
|
||||||
// It also relates the preconditioned and unpreconditioned systems described in Appendix B.2.
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::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<Ls; ++s){
|
|
||||||
if(s == 0) {
|
|
||||||
axpby_ssp_pminus(chi, b, psi, -c, psi, s, s+1);
|
|
||||||
axpby_ssp_pplus (chi, 1.0, chi, mq1*c, psi, s, Ls-1);
|
|
||||||
} else if(s == (Ls-1)) {
|
|
||||||
axpby_ssp_pminus(chi, b, psi, mq1*c, psi, s, 0);
|
|
||||||
axpby_ssp_pplus (chi, 1.0, chi, -c, psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pminus(chi, b, psi, -c, psi, s, s+1);
|
|
||||||
axpby_ssp_pplus (chi, 1.0, chi, -c, psi, s, s-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::DtildeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
RealD m = this->mq1;
|
|
||||||
RealD c = 0.5 * this->alpha;
|
|
||||||
RealD d = 0.5;
|
|
||||||
|
|
||||||
RealD DtInv_p(0.0), DtInv_m(0.0);
|
|
||||||
RealD N = std::pow(c+d,Ls) + m*std::pow(c-d,Ls);
|
|
||||||
FermionField tmp(this->FermionGrid());
|
|
||||||
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
for(int sp=0; sp<Ls; ++sp){
|
|
||||||
|
|
||||||
DtInv_p = m * std::pow(-1.0,s-sp+1) * std::pow(c-d,Ls+s-sp) / std::pow(c+d,s-sp+1) / N;
|
|
||||||
DtInv_p += (s < sp) ? 0.0 : std::pow(-1.0,s-sp) * std::pow(c-d,s-sp) / std::pow(c+d,s-sp+1);
|
|
||||||
DtInv_m = m * std::pow(-1.0,sp-s+1) * std::pow(c-d,Ls+sp-s) / std::pow(c+d,sp-s+1) / N;
|
|
||||||
DtInv_m += (s > sp) ? 0.0 : std::pow(-1.0,sp-s) * std::pow(c-d,sp-s) / std::pow(c+d,sp-s+1);
|
|
||||||
|
|
||||||
if(sp == 0){
|
|
||||||
axpby_ssp_pplus (tmp, 0.0, tmp, DtInv_p, psi, s, sp);
|
|
||||||
axpby_ssp_pminus(tmp, 0.0, tmp, DtInv_m, psi, s, sp);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pplus (tmp, 1.0, tmp, DtInv_p, psi, s, sp);
|
|
||||||
axpby_ssp_pminus(tmp, 1.0, tmp, DtInv_m, psi, s, sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************************************/
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
RealD MobiusEOFAFermion<Impl>::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<class Impl>
|
|
||||||
RealD MobiusEOFAFermion<Impl>::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<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
std::vector<Coeff_t> diag(Ls,1.0);
|
|
||||||
std::vector<Coeff_t> upper(Ls,-1.0); upper[Ls-1] = this->mq1;
|
|
||||||
std::vector<Coeff_t> 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<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
std::vector<Coeff_t> diag(Ls,1.0);
|
|
||||||
std::vector<Coeff_t> upper(Ls,-1.0); upper[Ls-1] = this->mq1;
|
|
||||||
std::vector<Coeff_t> lower(Ls,-1.0); lower[0] = this->mq1;
|
|
||||||
|
|
||||||
// no shift term
|
|
||||||
if(this->shift == 0.0){ this->M5Ddag(psi, chi, chi, lower, diag, upper); }
|
|
||||||
|
|
||||||
// fused M + shift operation
|
|
||||||
else{ this->M5Ddag_shift(psi, chi, chi, lower, diag, upper, Mooee_shift); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// half checkerboard operations
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::Mooee(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
// coefficients of Mooee
|
|
||||||
std::vector<Coeff_t> diag = this->bee;
|
|
||||||
std::vector<Coeff_t> upper(Ls);
|
|
||||||
std::vector<Coeff_t> lower(Ls);
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
upper[s] = -this->cee[s];
|
|
||||||
lower[s] = -this->cee[s];
|
|
||||||
}
|
|
||||||
upper[Ls-1] *= -this->mq1;
|
|
||||||
lower[0] *= -this->mq1;
|
|
||||||
|
|
||||||
// no shift term
|
|
||||||
if(this->shift == 0.0){ this->M5D(psi, psi, chi, lower, diag, upper); }
|
|
||||||
|
|
||||||
// fused M + shift operation
|
|
||||||
else { this->M5D_shift(psi, psi, chi, lower, diag, upper, Mooee_shift); }
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
// coefficients of MooeeDag
|
|
||||||
std::vector<Coeff_t> diag = this->bee;
|
|
||||||
std::vector<Coeff_t> upper(Ls);
|
|
||||||
std::vector<Coeff_t> lower(Ls);
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
upper[s] = -this->cee[s+1];
|
|
||||||
lower[s] = this->mq1*this->cee[Ls-1];
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
upper[s] = this->mq1*this->cee[0];
|
|
||||||
lower[s] = -this->cee[s-1];
|
|
||||||
} else {
|
|
||||||
upper[s] = -this->cee[s+1];
|
|
||||||
lower[s] = -this->cee[s-1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no shift term
|
|
||||||
if(this->shift == 0.0){ this->M5Ddag(psi, psi, chi, lower, diag, upper); }
|
|
||||||
|
|
||||||
// fused M + shift operation
|
|
||||||
else{ this->M5Ddag_shift(psi, psi, chi, lower, diag, upper, Mooee_shift); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************************/
|
|
||||||
|
|
||||||
// Computes coefficients for applying Cayley preconditioned shift operators
|
|
||||||
// (Mooee + \Delta) --> Mooee_shift
|
|
||||||
// (Mooee + \Delta)^{-1} --> MooeeInv_shift_lc, MooeeInv_shift_norm
|
|
||||||
// (Mooee + \Delta)^{-dag} --> MooeeInvDag_shift_lc, MooeeInvDag_shift_norm
|
|
||||||
// For the latter two cases, the operation takes the form
|
|
||||||
// [ (Mooee + \Delta)^{-1} \psi ]_{i} = Mooee_{ij} \psi_{j} +
|
|
||||||
// ( MooeeInv_shift_norm )_{i} ( \sum_{j} [ MooeeInv_shift_lc ]_{j} P_{pm} \psi_{j} )
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::SetCoefficientsPrecondShiftOps()
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int pm = this->pm;
|
|
||||||
RealD alpha = this->alpha;
|
|
||||||
RealD k = this->k;
|
|
||||||
RealD mq1 = this->mq1;
|
|
||||||
RealD shift = this->shift;
|
|
||||||
|
|
||||||
// Initialize
|
|
||||||
Mooee_shift.resize(Ls);
|
|
||||||
MooeeInv_shift_lc.resize(Ls);
|
|
||||||
MooeeInv_shift_norm.resize(Ls);
|
|
||||||
MooeeInvDag_shift_lc.resize(Ls);
|
|
||||||
MooeeInvDag_shift_norm.resize(Ls);
|
|
||||||
|
|
||||||
// Construct Mooee_shift
|
|
||||||
int idx(0);
|
|
||||||
Coeff_t N = ( (pm == 1) ? 1.0 : -1.0 ) * (2.0*shift*k) *
|
|
||||||
( std::pow(alpha+1.0,Ls) + mq1*std::pow(alpha-1.0,Ls) );
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
idx = (pm == 1) ? (s) : (Ls-1-s);
|
|
||||||
Mooee_shift[idx] = N * std::pow(-1.0,s) * std::pow(alpha-1.0,s) / std::pow(alpha+1.0,Ls+s+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tridiagonal solve for MooeeInvDag_shift_lc
|
|
||||||
{
|
|
||||||
Coeff_t m(0.0);
|
|
||||||
std::vector<Coeff_t> d = Mooee_shift;
|
|
||||||
std::vector<Coeff_t> u(Ls,0.0);
|
|
||||||
std::vector<Coeff_t> y(Ls,0.0);
|
|
||||||
std::vector<Coeff_t> q(Ls,0.0);
|
|
||||||
if(pm == 1){ u[0] = 1.0; }
|
|
||||||
else{ u[Ls-1] = 1.0; }
|
|
||||||
|
|
||||||
// Tridiagonal matrix algorithm + Sherman-Morrison formula
|
|
||||||
//
|
|
||||||
// We solve
|
|
||||||
// ( Mooee' + u \otimes v ) MooeeInvDag_shift_lc = Mooee_shift
|
|
||||||
// where Mooee' is the tridiagonal part of Mooee_{+}, and
|
|
||||||
// u = (1,0,...,0) and v = (0,...,0,mq1*cee[0]) are chosen
|
|
||||||
// so that the outer-product u \otimes v gives the (0,Ls-1)
|
|
||||||
// entry of Mooee_{+}.
|
|
||||||
//
|
|
||||||
// We do this as two solves: Mooee'*y = d and Mooee'*q = u,
|
|
||||||
// and then construct the solution to the original system
|
|
||||||
// MooeeInvDag_shift_lc = y - <v,y> / ( 1 + <v,q> ) q
|
|
||||||
if(pm == 1){
|
|
||||||
for(int s=1; s<Ls; ++s){
|
|
||||||
m = -this->cee[s] / this->bee[s-1];
|
|
||||||
d[s] -= m*d[s-1];
|
|
||||||
u[s] -= m*u[s-1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
y[Ls-1] = d[Ls-1] / this->bee[Ls-1];
|
|
||||||
q[Ls-1] = u[Ls-1] / this->bee[Ls-1];
|
|
||||||
for(int s=Ls-2; s>=0; --s){
|
|
||||||
if(pm == 1){
|
|
||||||
y[s] = d[s] / this->bee[s];
|
|
||||||
q[s] = u[s] / this->bee[s];
|
|
||||||
} else {
|
|
||||||
y[s] = ( d[s] + this->cee[s]*y[s+1] ) / this->bee[s];
|
|
||||||
q[s] = ( u[s] + this->cee[s]*q[s+1] ) / this->bee[s];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct MooeeInvDag_shift_lc
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
if(pm == 1){
|
|
||||||
MooeeInvDag_shift_lc[s] = y[s] - mq1*this->cee[0]*y[Ls-1] /
|
|
||||||
(1.0+mq1*this->cee[0]*q[Ls-1]) * q[s];
|
|
||||||
} else {
|
|
||||||
MooeeInvDag_shift_lc[s] = y[s] - mq1*this->cee[Ls-1]*y[0] /
|
|
||||||
(1.0+mq1*this->cee[Ls-1]*q[0]) * q[s];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute remaining coefficients
|
|
||||||
N = (pm == 1) ? (1.0 + MooeeInvDag_shift_lc[Ls-1]) : (1.0 + MooeeInvDag_shift_lc[0]);
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
|
|
||||||
// MooeeInv_shift_lc
|
|
||||||
if(pm == 1){ MooeeInv_shift_lc[s] = std::pow(this->bee[s],s) * std::pow(this->cee[s],Ls-1-s); }
|
|
||||||
else{ MooeeInv_shift_lc[s] = std::pow(this->bee[s],Ls-1-s) * std::pow(this->cee[s],s); }
|
|
||||||
|
|
||||||
// MooeeInv_shift_norm
|
|
||||||
MooeeInv_shift_norm[s] = -MooeeInvDag_shift_lc[s] /
|
|
||||||
( std::pow(this->bee[s],Ls) + mq1*std::pow(this->cee[s],Ls) ) / N;
|
|
||||||
|
|
||||||
// MooeeInvDag_shift_norm
|
|
||||||
if(pm == 1){ MooeeInvDag_shift_norm[s] = -std::pow(this->bee[s],s) * std::pow(this->cee[s],Ls-1-s) /
|
|
||||||
( std::pow(this->bee[s],Ls) + mq1*std::pow(this->cee[s],Ls) ) / N; }
|
|
||||||
else{ MooeeInvDag_shift_norm[s] = -std::pow(this->bee[s],Ls-1-s) * std::pow(this->cee[s],s) /
|
|
||||||
( std::pow(this->bee[s],Ls) + mq1*std::pow(this->cee[s],Ls) ) / N; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recompute coefficients for a different value of shift constant
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::RefreshShiftCoefficients(RealD new_shift)
|
|
||||||
{
|
|
||||||
this->shift = new_shift;
|
|
||||||
if(new_shift != 0.0){
|
|
||||||
SetCoefficientsPrecondShiftOps();
|
|
||||||
} else {
|
|
||||||
int Ls = this->Ls;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInternalCompute(int dag, int inv,
|
|
||||||
Vector<iSinglet<Simd> >& Matp, Vector<iSinglet<Simd> >& Matm)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
GridBase* grid = this->FermionRedBlackGrid();
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
|
|
||||||
if(LLs == Ls){ return; } // Not vectorised in 5th direction
|
|
||||||
|
|
||||||
Eigen::MatrixXcd Pplus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
|
||||||
Eigen::MatrixXcd Pminus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
|
||||||
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
Pplus(s,s) = this->bee[s];
|
|
||||||
Pminus(s,s) = this->bee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pminus(s,s+1) = -this->cee[s];
|
|
||||||
Pplus(s+1,s) = -this->cee[s+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
Pplus (0,Ls-1) = this->mq1*this->cee[0];
|
|
||||||
Pminus(Ls-1,0) = this->mq1*this->cee[Ls-1];
|
|
||||||
|
|
||||||
if(this->shift != 0.0){
|
|
||||||
RealD c = 0.5 * this->alpha;
|
|
||||||
RealD d = 0.5;
|
|
||||||
RealD N = this->shift * this->k * ( std::pow(c+d,Ls) + this->mq1*std::pow(c-d,Ls) );
|
|
||||||
if(this->pm == 1) {
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
Pplus(s,Ls-1) += N * std::pow(-1.0,s) * std::pow(c-d,s) / std::pow(c+d,Ls+s+1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
Pminus(s,0) += N * std::pow(-1.0,s+1) * std::pow(c-d,Ls-1-s) / std::pow(c+d,2*Ls-s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Eigen::MatrixXcd PplusMat ;
|
|
||||||
Eigen::MatrixXcd PminusMat;
|
|
||||||
|
|
||||||
if(inv) {
|
|
||||||
PplusMat = Pplus.inverse();
|
|
||||||
PminusMat = Pminus.inverse();
|
|
||||||
} else {
|
|
||||||
PplusMat = Pplus;
|
|
||||||
PminusMat = Pminus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dag){
|
|
||||||
PplusMat.adjointInPlace();
|
|
||||||
PminusMat.adjointInPlace();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename SiteHalfSpinor::scalar_type scalar_type;
|
|
||||||
const int Nsimd = Simd::Nsimd();
|
|
||||||
Matp.resize(Ls*LLs);
|
|
||||||
Matm.resize(Ls*LLs);
|
|
||||||
|
|
||||||
for(int s2=0; s2<Ls; s2++){
|
|
||||||
for(int s1=0; s1<LLs; s1++){
|
|
||||||
int istride = LLs;
|
|
||||||
int ostride = 1;
|
|
||||||
Simd Vp;
|
|
||||||
Simd Vm;
|
|
||||||
scalar_type *sp = (scalar_type*) &Vp;
|
|
||||||
scalar_type *sm = (scalar_type*) &Vm;
|
|
||||||
for(int l=0; l<Nsimd; l++){
|
|
||||||
if(switcheroo<Coeff_t>::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);
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/MobiusEOFAFermion.h
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 <Grid/qcd/action/fermion/AbstractEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
class MobiusEOFAFermion : public AbstractEOFAFermion<Impl>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
INHERIT_IMPL_TYPES(Impl);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Shift operator coefficients for red-black preconditioned Mobius EOFA
|
|
||||||
std::vector<Coeff_t> Mooee_shift;
|
|
||||||
std::vector<Coeff_t> MooeeInv_shift_lc;
|
|
||||||
std::vector<Coeff_t> MooeeInv_shift_norm;
|
|
||||||
std::vector<Coeff_t> MooeeInvDag_shift_lc;
|
|
||||||
std::vector<Coeff_t> 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<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper);
|
|
||||||
|
|
||||||
void M5D_shift(const FermionField& psi, const FermionField& phi, FermionField& chi,
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper,
|
|
||||||
std::vector<Coeff_t>& shift_coeffs);
|
|
||||||
|
|
||||||
void M5Ddag(const FermionField& psi, const FermionField& phi, FermionField& chi,
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper);
|
|
||||||
|
|
||||||
void M5Ddag_shift(const FermionField& psi, const FermionField& phi, FermionField& chi,
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper,
|
|
||||||
std::vector<Coeff_t>& shift_coeffs);
|
|
||||||
|
|
||||||
void MooeeInternal(const FermionField& in, FermionField& out, int dag, int inv);
|
|
||||||
|
|
||||||
void MooeeInternalCompute(int dag, int inv, Vector<iSinglet<Simd>>& Matp, Vector<iSinglet<Simd>>& Matm);
|
|
||||||
|
|
||||||
void MooeeInternalAsm(const FermionField& in, FermionField& out, int LLs, int site,
|
|
||||||
Vector<iSinglet<Simd>>& Matp, Vector<iSinglet<Simd>>& Matm);
|
|
||||||
|
|
||||||
void MooeeInternalZAsm(const FermionField& in, FermionField& out, int LLs, int site,
|
|
||||||
Vector<iSinglet<Simd>>& Matp, Vector<iSinglet<Simd>>& 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_MOBIUS_EOFA(A)\
|
|
||||||
template void MobiusEOFAFermion<A>::M5D(const FermionField& psi, const FermionField& phi, FermionField& chi, \
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper); \
|
|
||||||
template void MobiusEOFAFermion<A>::M5D_shift(const FermionField& psi, const FermionField& phi, FermionField& chi, \
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper, std::vector<Coeff_t>& shift_coeffs); \
|
|
||||||
template void MobiusEOFAFermion<A>::M5Ddag(const FermionField& psi, const FermionField& phi, FermionField& chi, \
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper); \
|
|
||||||
template void MobiusEOFAFermion<A>::M5Ddag_shift(const FermionField& psi, const FermionField& phi, FermionField& chi, \
|
|
||||||
std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper, std::vector<Coeff_t>& shift_coeffs); \
|
|
||||||
template void MobiusEOFAFermion<A>::MooeeInv(const FermionField& psi, FermionField& chi); \
|
|
||||||
template void MobiusEOFAFermion<A>::MooeeInv_shift(const FermionField& psi, FermionField& chi); \
|
|
||||||
template void MobiusEOFAFermion<A>::MooeeInvDag(const FermionField& psi, FermionField& chi); \
|
|
||||||
template void MobiusEOFAFermion<A>::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
|
|
||||||
@@ -1,429 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/MobiusEOFAFermioncache.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/MobiusEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
// FIXME -- make a version of these routines with site loop outermost for cache reuse.
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D(const FermionField &psi, const FermionField &phi, FermionField &chi,
|
|
||||||
std::vector<Coeff_t> &lower, std::vector<Coeff_t> &diag, std::vector<Coeff_t> &upper)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
|
|
||||||
assert(phi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
// Flops = 6.0*(Nc*Ns) *Ls*vol
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
if(s==0){
|
|
||||||
spProj5m(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+Ls-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
spProj5m(tmp, psi._odata[ss+0]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else {
|
|
||||||
spProj5m(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D_shift(const FermionField &psi, const FermionField &phi, FermionField &chi,
|
|
||||||
std::vector<Coeff_t> &lower, std::vector<Coeff_t> &diag, std::vector<Coeff_t> &upper,
|
|
||||||
std::vector<Coeff_t> &shift_coeffs)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int shift_s = (this->pm == 1) ? (Ls-1) : 0; // s-component modified by shift operator
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
|
|
||||||
assert(phi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
// Flops = 6.0*(Nc*Ns) *Ls*vol
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
if(s==0){
|
|
||||||
spProj5m(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+Ls-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
spProj5m(tmp, psi._odata[ss+0]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else {
|
|
||||||
spProj5m(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5p(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
}
|
|
||||||
if(this->pm == 1){ spProj5p(tmp, psi._odata[ss+shift_s]); }
|
|
||||||
else{ spProj5m(tmp, psi._odata[ss+shift_s]); }
|
|
||||||
chi[ss+s] = chi[ss+s] + shift_coeffs[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag(const FermionField &psi, const FermionField &phi, FermionField &chi,
|
|
||||||
std::vector<Coeff_t> &lower, std::vector<Coeff_t> &diag, std::vector<Coeff_t> &upper)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
|
|
||||||
assert(phi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
// Flops = 6.0*(Nc*Ns) *Ls*vol
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
spProj5p(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+Ls-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
spProj5p(tmp, psi._odata[ss+0]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else {
|
|
||||||
spProj5p(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag_shift(const FermionField &psi, const FermionField &phi, FermionField &chi,
|
|
||||||
std::vector<Coeff_t> &lower, std::vector<Coeff_t> &diag, std::vector<Coeff_t> &upper,
|
|
||||||
std::vector<Coeff_t> &shift_coeffs)
|
|
||||||
{
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int shift_s = (this->pm == 1) ? (Ls-1) : 0; // s-component modified by shift operator
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
|
|
||||||
assert(phi.checkerboard == psi.checkerboard);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
// Flops = 6.0*(Nc*Ns) *Ls*vol
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
chi[ss+Ls-1] = zero;
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
spProj5p(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+Ls-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else if(s==(Ls-1)) {
|
|
||||||
spProj5p(tmp, psi._odata[ss+0]);
|
|
||||||
chi[ss+s] = chi[ss+s] + diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
} else {
|
|
||||||
spProj5p(tmp, psi._odata[ss+s+1]);
|
|
||||||
chi[ss+s] = diag[s]*phi[ss+s] + upper[s]*tmp;
|
|
||||||
spProj5m(tmp, psi._odata[ss+s-1]);
|
|
||||||
chi[ss+s] = chi[ss+s] + lower[s]*tmp;
|
|
||||||
}
|
|
||||||
if(this->pm == 1){ spProj5p(tmp, psi._odata[ss+s]); }
|
|
||||||
else{ spProj5m(tmp, psi._odata[ss+s]); }
|
|
||||||
chi[ss+shift_s] = chi[ss+shift_s] + shift_coeffs[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv(const FermionField &psi, FermionField &chi)
|
|
||||||
{
|
|
||||||
if(this->shift != 0.0){ MooeeInv_shift(psi,chi); return; }
|
|
||||||
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
|
|
||||||
// Apply (L^{\prime})^{-1}
|
|
||||||
chi[ss] = psi[ss]; // chi[0]=psi[0]
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
spProj5p(tmp, chi[ss+s-1]);
|
|
||||||
chi[ss+s] = psi[ss+s] - this->lee[s-1]*tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
|
|
||||||
spProj5m(tmp, chi[ss+s]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] - this->leem[s]*tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-1} D^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[s] + 1/d chi[s]
|
|
||||||
spProj5p(tmp, chi[ss+Ls-1]);
|
|
||||||
chi[ss+s] = (1.0/this->dee[s])*chi[ss+s] - (this->ueem[s]/this->dee[Ls-1])*tmp;
|
|
||||||
}
|
|
||||||
chi[ss+Ls-1] = (1.0/this->dee[Ls-1])*chi[ss+Ls-1];
|
|
||||||
|
|
||||||
// Apply U^{-1}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
spProj5m(tmp, chi[ss+s+1]);
|
|
||||||
chi[ss+s] = chi[ss+s] - this->uee[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv_shift(const FermionField &psi, FermionField &chi)
|
|
||||||
{
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
|
|
||||||
auto tmp1 = psi._odata[0];
|
|
||||||
auto tmp2 = psi._odata[0];
|
|
||||||
auto tmp2_spProj = psi._odata[0];
|
|
||||||
|
|
||||||
// Apply (L^{\prime})^{-1} and accumulate MooeeInv_shift_lc[j]*psi[j] in tmp2
|
|
||||||
chi[ss] = psi[ss]; // chi[0]=psi[0]
|
|
||||||
tmp2 = MooeeInv_shift_lc[0]*psi[ss];
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
spProj5p(tmp1, chi[ss+s-1]);
|
|
||||||
chi[ss+s] = psi[ss+s] - this->lee[s-1]*tmp1;
|
|
||||||
tmp2 = tmp2 + MooeeInv_shift_lc[s]*psi[ss+s];
|
|
||||||
}
|
|
||||||
if(this->pm == 1){ spProj5p(tmp2_spProj, tmp2);}
|
|
||||||
else{ spProj5m(tmp2_spProj, tmp2); }
|
|
||||||
|
|
||||||
// L_m^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
|
|
||||||
spProj5m(tmp1, chi[ss+s]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] - this->leem[s]*tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-1} D^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[s] + 1/d chi[s]
|
|
||||||
spProj5p(tmp1, chi[ss+Ls-1]);
|
|
||||||
chi[ss+s] = (1.0/this->dee[s])*chi[ss+s] - (this->ueem[s]/this->dee[Ls-1])*tmp1;
|
|
||||||
}
|
|
||||||
// chi[ss+Ls-1] = (1.0/this->dee[Ls-1])*chi[ss+Ls-1] + MooeeInv_shift_norm[Ls-1]*tmp2_spProj;
|
|
||||||
chi[ss+Ls-1] = (1.0/this->dee[Ls-1])*chi[ss+Ls-1];
|
|
||||||
spProj5m(tmp1, chi[ss+Ls-1]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] + MooeeInv_shift_norm[Ls-1]*tmp2_spProj;
|
|
||||||
|
|
||||||
// Apply U^{-1} and add shift term
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
chi[ss+s] = chi[ss+s] - this->uee[s]*tmp1;
|
|
||||||
spProj5m(tmp1, chi[ss+s]);
|
|
||||||
chi[ss+s] = chi[ss+s] + MooeeInv_shift_norm[s]*tmp2_spProj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag(const FermionField &psi, FermionField &chi)
|
|
||||||
{
|
|
||||||
if(this->shift != 0.0){ MooeeInvDag_shift(psi,chi); return; }
|
|
||||||
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
|
|
||||||
auto tmp = psi._odata[0];
|
|
||||||
|
|
||||||
// Apply (U^{\prime})^{-dag}
|
|
||||||
chi[ss] = psi[ss];
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
spProj5m(tmp, chi[ss+s-1]);
|
|
||||||
chi[ss+s] = psi[ss+s] - this->uee[s-1]*tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-\dag}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
spProj5p(tmp, chi[ss+s]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] - this->ueem[s]*tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-\dag} D^{-dag}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
spProj5m(tmp, chi[ss+Ls-1]);
|
|
||||||
chi[ss+s] = (1.0/this->dee[s])*chi[ss+s] - (this->leem[s]/this->dee[Ls-1])*tmp;
|
|
||||||
}
|
|
||||||
chi[ss+Ls-1] = (1.0/this->dee[Ls-1])*chi[ss+Ls-1];
|
|
||||||
|
|
||||||
// Apply L^{-dag}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
spProj5p(tmp, chi[ss+s+1]);
|
|
||||||
chi[ss+s] = chi[ss+s] - this->lee[s]*tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag_shift(const FermionField &psi, FermionField &chi)
|
|
||||||
{
|
|
||||||
GridBase *grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=Ls){
|
|
||||||
|
|
||||||
auto tmp1 = psi._odata[0];
|
|
||||||
auto tmp2 = psi._odata[0];
|
|
||||||
auto tmp2_spProj = psi._odata[0];
|
|
||||||
|
|
||||||
// Apply (U^{\prime})^{-dag} and accumulate MooeeInvDag_shift_lc[j]*psi[j] in tmp2
|
|
||||||
chi[ss] = psi[ss];
|
|
||||||
tmp2 = MooeeInvDag_shift_lc[0]*psi[ss];
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
spProj5m(tmp1, chi[ss+s-1]);
|
|
||||||
chi[ss+s] = psi[ss+s] - this->uee[s-1]*tmp1;
|
|
||||||
tmp2 = tmp2 + MooeeInvDag_shift_lc[s]*psi[ss+s];
|
|
||||||
}
|
|
||||||
if(this->pm == 1){ spProj5p(tmp2_spProj, tmp2);}
|
|
||||||
else{ spProj5m(tmp2_spProj, tmp2); }
|
|
||||||
|
|
||||||
// U_m^{-\dag}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
spProj5p(tmp1, chi[ss+s]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] - this->ueem[s]*tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-\dag} D^{-dag}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
spProj5m(tmp1, chi[ss+Ls-1]);
|
|
||||||
chi[ss+s] = (1.0/this->dee[s])*chi[ss+s] - (this->leem[s]/this->dee[Ls-1])*tmp1;
|
|
||||||
}
|
|
||||||
chi[ss+Ls-1] = (1.0/this->dee[Ls-1])*chi[ss+Ls-1];
|
|
||||||
spProj5p(tmp1, chi[ss+Ls-1]);
|
|
||||||
chi[ss+Ls-1] = chi[ss+Ls-1] + MooeeInvDag_shift_norm[Ls-1]*tmp2_spProj;
|
|
||||||
|
|
||||||
// Apply L^{-dag}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
chi[ss+s] = chi[ss+s] - this->lee[s]*tmp1;
|
|
||||||
spProj5p(tmp1, chi[ss+s]);
|
|
||||||
chi[ss+s] = chi[ss+s] + MooeeInvDag_shift_norm[s]*tmp2_spProj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOBIUS_EOFA_DPERP_CACHE
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplD);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplDF);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,184 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/MobiusEOFAFermiondense.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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_Eigen_Dense.h>
|
|
||||||
#include <Grid/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/MobiusEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dense matrix versions of routines
|
|
||||||
*/
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerNo, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv_shift(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerNo, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerYes, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag_shift(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerYes, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::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;
|
|
||||||
|
|
||||||
int pm = this->pm;
|
|
||||||
RealD shift = this->shift;
|
|
||||||
RealD alpha = this->alpha;
|
|
||||||
RealD k = this->k;
|
|
||||||
RealD mq1 = this->mq1;
|
|
||||||
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
|
|
||||||
assert(Ls==LLs);
|
|
||||||
|
|
||||||
Eigen::MatrixXd Pplus = Eigen::MatrixXd::Zero(Ls,Ls);
|
|
||||||
Eigen::MatrixXd Pminus = Eigen::MatrixXd::Zero(Ls,Ls);
|
|
||||||
|
|
||||||
for(int s=0;s<Ls;s++){
|
|
||||||
Pplus(s,s) = this->bee[s];
|
|
||||||
Pminus(s,s) = this->bee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pminus(s,s+1) = -this->cee[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
Pplus(s+1,s) = -this->cee[s+1];
|
|
||||||
}
|
|
||||||
Pplus (0,Ls-1) = mq1*this->cee[0];
|
|
||||||
Pminus(Ls-1,0) = mq1*this->cee[Ls-1];
|
|
||||||
|
|
||||||
if(shift != 0.0){
|
|
||||||
Coeff_t N = 2.0 * ( std::pow(alpha+1.0,Ls) + mq1*std::pow(alpha-1.0,Ls) );
|
|
||||||
for(int s=0; s<Ls; ++s){
|
|
||||||
if(pm == 1){ Pplus(s,Ls-1) += shift * k * N * std::pow(-1.0,s) * std::pow(alpha-1.0,s) / std::pow(alpha+1.0,Ls+s+1); }
|
|
||||||
else{ Pminus(Ls-1-s,Ls-1) -= shift * k * N * std::pow(-1.0,s) * std::pow(alpha-1.0,s) / std::pow(alpha+1.0,Ls+s+1); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Eigen::MatrixXd PplusMat ;
|
|
||||||
Eigen::MatrixXd PminusMat;
|
|
||||||
|
|
||||||
if(inv){
|
|
||||||
PplusMat = Pplus.inverse();
|
|
||||||
PminusMat = Pminus.inverse();
|
|
||||||
} else {
|
|
||||||
PplusMat = Pplus;
|
|
||||||
PminusMat = Pminus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dag){
|
|
||||||
PplusMat.adjointInPlace();
|
|
||||||
PminusMat.adjointInPlace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the non-vectorised s-direction this is simple
|
|
||||||
|
|
||||||
for(auto site=0; site<vol; site++){
|
|
||||||
|
|
||||||
SiteSpinor SiteChi;
|
|
||||||
SiteHalfSpinor SitePplus;
|
|
||||||
SiteHalfSpinor SitePminus;
|
|
||||||
|
|
||||||
for(int s1=0; s1<Ls; s1++){
|
|
||||||
SiteChi = zero;
|
|
||||||
for(int s2=0; s2<Ls; s2++){
|
|
||||||
int lex2 = s2 + Ls*site;
|
|
||||||
if(PplusMat(s1,s2) != 0.0){
|
|
||||||
spProj5p(SitePplus,psi[lex2]);
|
|
||||||
accumRecon5p(SiteChi, PplusMat(s1,s2)*SitePplus);
|
|
||||||
}
|
|
||||||
if(PminusMat(s1,s2) != 0.0){
|
|
||||||
spProj5m(SitePminus, psi[lex2]);
|
|
||||||
accumRecon5m(SiteChi, PminusMat(s1,s2)*SitePminus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chi[s1+Ls*site] = SiteChi*0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOBIUS_EOFA_DPERP_DENSE
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplD);
|
|
||||||
|
|
||||||
template void MobiusEOFAFermion<GparityWilsonImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<GparityWilsonImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<WilsonImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<WilsonImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZWilsonImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZWilsonImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplDF);
|
|
||||||
|
|
||||||
template void MobiusEOFAFermion<GparityWilsonImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<GparityWilsonImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<WilsonImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<WilsonImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZWilsonImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZWilsonImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,290 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/MobiusEOFAFermionssp.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/MobiusEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
// FIXME -- make a version of these routines with site loop outermost for cache reuse.
|
|
||||||
// Pminus fowards
|
|
||||||
// Pplus backwards
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pplus (chi, one, chi, lower[s], psi, s, Ls-1);
|
|
||||||
} else if (s==(Ls-1)) {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, 0);
|
|
||||||
axpby_ssp_pplus (chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pplus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D_shift(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper,
|
|
||||||
std::vector<Coeff_t>& shift_coeffs)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pplus (chi, one, chi, lower[s], psi, s, Ls-1);
|
|
||||||
} else if (s==(Ls-1)) {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, 0);
|
|
||||||
axpby_ssp_pplus (chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pminus(chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pplus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
}
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, shift_coeffs[s], psi, s, Ls-1); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, shift_coeffs[s], psi, s, 0); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, Ls-1);
|
|
||||||
} else if (s==(Ls-1)) {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, 0);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag_shift(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper,
|
|
||||||
std::vector<Coeff_t>& shift_coeffs)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(s==0) {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, Ls-1);
|
|
||||||
} else if (s==(Ls-1)) {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, 0);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
} else {
|
|
||||||
axpby_ssp_pplus (chi, diag[s], phi, upper[s], psi, s, s+1);
|
|
||||||
axpby_ssp_pminus(chi, one, chi, lower[s], psi, s, s-1);
|
|
||||||
}
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, shift_coeffs[s], psi, Ls-1, s); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, shift_coeffs[s], psi, 0, s); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
if(this->shift != 0.0){ MooeeInv_shift(psi,chi); return; }
|
|
||||||
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
Coeff_t czero(0.0);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
// Apply (L^{\prime})^{-1}
|
|
||||||
axpby_ssp(chi, one, psi, czero, psi, 0, 0); // chi[0]=psi[0]
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
axpby_ssp_pplus(chi, one, psi, -this->lee[s-1], chi, s, s-1);// recursion Psi[s] -lee P_+ chi[s-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
|
|
||||||
axpby_ssp_pminus(chi, one, chi, -this->leem[s], chi, Ls-1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-1} D^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pplus(chi, one/this->dee[s], chi, -this->ueem[s]/this->dee[Ls-1], chi, s, Ls-1);
|
|
||||||
}
|
|
||||||
axpby_ssp(chi, one/this->dee[Ls-1], chi, czero, chi, Ls-1, Ls-1);
|
|
||||||
|
|
||||||
// Apply U^{-1}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
axpby_ssp_pminus(chi, one, chi, -this->uee[s], chi, s, s+1); // chi[Ls]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv_shift(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
Coeff_t czero(0.0);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
// Apply (L^{\prime})^{-1}
|
|
||||||
axpby_ssp(chi, one, psi, czero, psi, 0, 0); // chi[0]=psi[0]
|
|
||||||
axpby_ssp(tmp, czero, tmp, this->MooeeInv_shift_lc[0], psi, 0, 0);
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
axpby_ssp_pplus(chi, one, psi, -this->lee[s-1], chi, s, s-1);// recursion Psi[s] -lee P_+ chi[s-1]
|
|
||||||
axpby_ssp(tmp, one, tmp, this->MooeeInv_shift_lc[s], psi, 0, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
|
|
||||||
axpby_ssp_pminus(chi, one, chi, -this->leem[s], chi, Ls-1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-1} D^{-1}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pplus(chi, one/this->dee[s], chi, -this->ueem[s]/this->dee[Ls-1], chi, s, Ls-1);
|
|
||||||
}
|
|
||||||
axpby_ssp(chi, one/this->dee[Ls-1], chi, czero, chi, Ls-1, Ls-1);
|
|
||||||
|
|
||||||
// Apply U^{-1} and add shift term
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, this->MooeeInv_shift_norm[Ls-1], tmp, Ls-1, 0); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, this->MooeeInv_shift_norm[Ls-1], tmp, Ls-1, 0); }
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
axpby_ssp_pminus(chi, one, chi, -this->uee[s], chi, s, s+1); // chi[Ls]
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, this->MooeeInv_shift_norm[s], tmp, s, 0); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, this->MooeeInv_shift_norm[s], tmp, s, 0); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
if(this->shift != 0.0){ MooeeInvDag_shift(psi,chi); return; }
|
|
||||||
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
Coeff_t czero(0.0);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
// Apply (U^{\prime})^{-dagger}
|
|
||||||
axpby_ssp(chi, one, psi, czero, psi, 0, 0); // chi[0]=psi[0]
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
axpby_ssp_pminus(chi, one, psi, -conjugate(this->uee[s-1]), chi, s, s-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-\dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pplus(chi, one, chi, -conjugate(this->ueem[s]), chi, Ls-1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-\dagger} D^{-dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pminus(chi, one/conjugate(this->dee[s]), chi, -conjugate(this->leem[s]/this->dee[Ls-1]), chi, s, Ls-1);
|
|
||||||
}
|
|
||||||
axpby_ssp(chi, one/conjugate(this->dee[Ls-1]), chi, czero, chi, Ls-1, Ls-1);
|
|
||||||
|
|
||||||
// Apply L^{-dagger}
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
axpby_ssp_pplus(chi, one, chi, -conjugate(this->lee[s]), chi, s, s+1); // chi[Ls]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag_shift(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
Coeff_t czero(0.0);
|
|
||||||
chi.checkerboard = psi.checkerboard;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
|
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
// Apply (U^{\prime})^{-dagger} and accumulate (MooeeInvDag_shift_lc)_{j} \psi_{j} in tmp[0]
|
|
||||||
axpby_ssp(chi, one, psi, czero, psi, 0, 0); // chi[0]=psi[0]
|
|
||||||
axpby_ssp(tmp, czero, tmp, this->MooeeInvDag_shift_lc[0], psi, 0, 0);
|
|
||||||
for(int s=1; s<Ls; s++){
|
|
||||||
axpby_ssp_pminus(chi, one, psi, -conjugate(this->uee[s-1]), chi, s, s-1);
|
|
||||||
axpby_ssp(tmp, one, tmp, this->MooeeInvDag_shift_lc[s], psi, 0, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U_m^{-\dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pplus(chi, one, chi, -conjugate(this->ueem[s]), chi, Ls-1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// L_m^{-\dagger} D^{-dagger}
|
|
||||||
for(int s=0; s<Ls-1; s++){
|
|
||||||
axpby_ssp_pminus(chi, one/conjugate(this->dee[s]), chi, -conjugate(this->leem[s]/this->dee[Ls-1]), chi, s, Ls-1);
|
|
||||||
}
|
|
||||||
axpby_ssp(chi, one/conjugate(this->dee[Ls-1]), chi, czero, chi, Ls-1, Ls-1);
|
|
||||||
|
|
||||||
// Apply L^{-dagger} and add shift
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, this->MooeeInvDag_shift_norm[Ls-1], tmp, Ls-1, 0); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, this->MooeeInvDag_shift_norm[Ls-1], tmp, Ls-1, 0); }
|
|
||||||
for(int s=Ls-2; s>=0; s--){
|
|
||||||
axpby_ssp_pplus(chi, one, chi, -conjugate(this->lee[s]), chi, s, s+1); // chi[Ls]
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, this->MooeeInvDag_shift_norm[s], tmp, s, 0); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, this->MooeeInvDag_shift_norm[s], tmp, s, 0); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOBIUS_EOFA_DPERP_LINALG
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplD);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(WilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(GparityWilsonImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZWilsonImplDF);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,983 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/fermion/MobiusEOFAFermionvec.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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/qcd/action/fermion/FermionCore.h>
|
|
||||||
#include <Grid/qcd/action/fermion/MobiusEOFAFermion.h>
|
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
namespace QCD {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dense matrix versions of routines
|
|
||||||
*/
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerNo, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInv_shift(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerNo, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerYes, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInvDag_shift(const FermionField& psi, FermionField& chi)
|
|
||||||
{
|
|
||||||
this->MooeeInternal(psi, chi, DaggerYes, InverseYes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
const int nsimd = Simd::Nsimd();
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd>> u(LLs);
|
|
||||||
Vector<iSinglet<Simd>> l(LLs);
|
|
||||||
Vector<iSinglet<Simd>> 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; o<LLs; o++){ // outer
|
|
||||||
for(int i=0; i<nsimd; i++){ //inner
|
|
||||||
int s = o + i*LLs;
|
|
||||||
int ss = o*nsimd + i;
|
|
||||||
u_p[ss] = upper[s];
|
|
||||||
l_p[ss] = lower[s];
|
|
||||||
d_p[ss] = diag[s];
|
|
||||||
}}
|
|
||||||
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
assert(Nc == 3);
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); 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<LLs; v++){
|
|
||||||
|
|
||||||
int vp = (v+1)%LLs;
|
|
||||||
int vm = (v+LLs-1)%LLs;
|
|
||||||
|
|
||||||
spProj5m(hp, psi[ss+vp]);
|
|
||||||
spProj5p(hm, psi[ss+vm]);
|
|
||||||
|
|
||||||
if (vp <= v){ rotate(hp, hp, 1); }
|
|
||||||
if (vm >= 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<LLs; v++){
|
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp = (v == LLs-1) ? 0 : v+1;
|
|
||||||
int vm = (v == 0) ? LLs-1 : v-1;
|
|
||||||
|
|
||||||
Simd hp_00 = psi[ss+vp]()(2)(0);
|
|
||||||
Simd hp_01 = psi[ss+vp]()(2)(1);
|
|
||||||
Simd hp_02 = psi[ss+vp]()(2)(2);
|
|
||||||
Simd hp_10 = psi[ss+vp]()(3)(0);
|
|
||||||
Simd hp_11 = psi[ss+vp]()(3)(1);
|
|
||||||
Simd hp_12 = psi[ss+vp]()(3)(2);
|
|
||||||
|
|
||||||
Simd hm_00 = psi[ss+vm]()(0)(0);
|
|
||||||
Simd hm_01 = psi[ss+vm]()(0)(1);
|
|
||||||
Simd hm_02 = psi[ss+vm]()(0)(2);
|
|
||||||
Simd hm_10 = psi[ss+vm]()(1)(0);
|
|
||||||
Simd hm_11 = psi[ss+vm]()(1)(1);
|
|
||||||
Simd hm_12 = psi[ss+vm]()(1)(2);
|
|
||||||
|
|
||||||
if(vp <= v){
|
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can force these to real arithmetic and save 2x.
|
|
||||||
Simd p_00 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00);
|
|
||||||
Simd p_01 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01);
|
|
||||||
Simd p_02 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02);
|
|
||||||
Simd p_10 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10);
|
|
||||||
Simd p_11 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11);
|
|
||||||
Simd p_12 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12);
|
|
||||||
Simd p_20 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00);
|
|
||||||
Simd p_21 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01);
|
|
||||||
Simd p_22 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02);
|
|
||||||
Simd p_30 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10);
|
|
||||||
Simd p_31 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11);
|
|
||||||
Simd p_32 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12);
|
|
||||||
|
|
||||||
vstream(chi[ss+v]()(0)(0), p_00);
|
|
||||||
vstream(chi[ss+v]()(0)(1), p_01);
|
|
||||||
vstream(chi[ss+v]()(0)(2), p_02);
|
|
||||||
vstream(chi[ss+v]()(1)(0), p_10);
|
|
||||||
vstream(chi[ss+v]()(1)(1), p_11);
|
|
||||||
vstream(chi[ss+v]()(1)(2), p_12);
|
|
||||||
vstream(chi[ss+v]()(2)(0), p_20);
|
|
||||||
vstream(chi[ss+v]()(2)(1), p_21);
|
|
||||||
vstream(chi[ss+v]()(2)(2), p_22);
|
|
||||||
vstream(chi[ss+v]()(3)(0), p_30);
|
|
||||||
vstream(chi[ss+v]()(3)(1), p_31);
|
|
||||||
vstream(chi[ss+v]()(3)(2), p_32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5D_shift(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper,
|
|
||||||
std::vector<Coeff_t>& shift_coeffs)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
this->M5D(psi, phi, chi, lower, diag, upper);
|
|
||||||
|
|
||||||
// FIXME: possible gain from vectorizing shift operation as well?
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, shift_coeffs[s], psi, s, Ls-1); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, shift_coeffs[s], psi, s, 0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
const int nsimd = Simd::Nsimd();
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd>> u(LLs);
|
|
||||||
Vector<iSinglet<Simd>> l(LLs);
|
|
||||||
Vector<iSinglet<Simd>> d(LLs);
|
|
||||||
Vector<iSinglet<Simd>> s(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];
|
|
||||||
scalar_type* s_p = (scalar_type*) &s[0];
|
|
||||||
|
|
||||||
for(int o=0; o<LLs; o++){ // outer
|
|
||||||
for(int i=0; i<nsimd; i++){ //inner
|
|
||||||
int s = o + i*LLs;
|
|
||||||
int ss = o*nsimd + i;
|
|
||||||
u_p[ss] = upper[s];
|
|
||||||
l_p[ss] = lower[s];
|
|
||||||
d_p[ss] = diag[s];
|
|
||||||
s_p[ss] = shift_coeffs[s];
|
|
||||||
}}
|
|
||||||
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
assert(Nc == 3);
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=LLs){ // adds LLs
|
|
||||||
|
|
||||||
int vs = (this->pm == 1) ? LLs-1 : 0;
|
|
||||||
Simd hs_00 = (this->pm == 1) ? psi[ss+vs]()(2)(0) : psi[ss+vs]()(0)(0);
|
|
||||||
Simd hs_01 = (this->pm == 1) ? psi[ss+vs]()(2)(1) : psi[ss+vs]()(0)(1);
|
|
||||||
Simd hs_02 = (this->pm == 1) ? psi[ss+vs]()(2)(2) : psi[ss+vs]()(0)(2);
|
|
||||||
Simd hs_10 = (this->pm == 1) ? psi[ss+vs]()(3)(0) : psi[ss+vs]()(1)(0);
|
|
||||||
Simd hs_11 = (this->pm == 1) ? psi[ss+vs]()(3)(1) : psi[ss+vs]()(1)(1);
|
|
||||||
Simd hs_12 = (this->pm == 1) ? psi[ss+vs]()(3)(2) : psi[ss+vs]()(1)(2);
|
|
||||||
|
|
||||||
for(int v=0; v<LLs; v++){
|
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp = (v == LLs-1) ? 0 : v+1;
|
|
||||||
int vm = (v == 0) ? LLs-1 : v-1;
|
|
||||||
|
|
||||||
Simd hp_00 = psi[ss+vp]()(2)(0);
|
|
||||||
Simd hp_01 = psi[ss+vp]()(2)(1);
|
|
||||||
Simd hp_02 = psi[ss+vp]()(2)(2);
|
|
||||||
Simd hp_10 = psi[ss+vp]()(3)(0);
|
|
||||||
Simd hp_11 = psi[ss+vp]()(3)(1);
|
|
||||||
Simd hp_12 = psi[ss+vp]()(3)(2);
|
|
||||||
|
|
||||||
Simd hm_00 = psi[ss+vm]()(0)(0);
|
|
||||||
Simd hm_01 = psi[ss+vm]()(0)(1);
|
|
||||||
Simd hm_02 = psi[ss+vm]()(0)(2);
|
|
||||||
Simd hm_10 = psi[ss+vm]()(1)(0);
|
|
||||||
Simd hm_11 = psi[ss+vm]()(1)(1);
|
|
||||||
Simd hm_12 = psi[ss+vm]()(1)(2);
|
|
||||||
|
|
||||||
if(vp <= v){
|
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(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(this->pm == 1 && vs <= v){
|
|
||||||
hs_00.v = Optimization::Rotate::tRotate<2>(hs_00.v);
|
|
||||||
hs_01.v = Optimization::Rotate::tRotate<2>(hs_01.v);
|
|
||||||
hs_02.v = Optimization::Rotate::tRotate<2>(hs_02.v);
|
|
||||||
hs_10.v = Optimization::Rotate::tRotate<2>(hs_10.v);
|
|
||||||
hs_11.v = Optimization::Rotate::tRotate<2>(hs_11.v);
|
|
||||||
hs_12.v = Optimization::Rotate::tRotate<2>(hs_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(this->pm == -1 && vs >= v){
|
|
||||||
hs_00.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_00.v);
|
|
||||||
hs_01.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_01.v);
|
|
||||||
hs_02.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_02.v);
|
|
||||||
hs_10.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_10.v);
|
|
||||||
hs_11.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_11.v);
|
|
||||||
hs_12.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_12.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can force these to real arithmetic and save 2x.
|
|
||||||
Simd p_00 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_00);
|
|
||||||
Simd p_01 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_01);
|
|
||||||
Simd p_02 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_02);
|
|
||||||
Simd p_10 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_10);
|
|
||||||
Simd p_11 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_11);
|
|
||||||
Simd p_12 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_12);
|
|
||||||
Simd p_20 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_00)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00);
|
|
||||||
Simd p_21 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_01)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01);
|
|
||||||
Simd p_22 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_02)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02);
|
|
||||||
Simd p_30 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_10)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10);
|
|
||||||
Simd p_31 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_11)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11);
|
|
||||||
Simd p_32 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_12)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12);
|
|
||||||
|
|
||||||
vstream(chi[ss+v]()(0)(0), p_00);
|
|
||||||
vstream(chi[ss+v]()(0)(1), p_01);
|
|
||||||
vstream(chi[ss+v]()(0)(2), p_02);
|
|
||||||
vstream(chi[ss+v]()(1)(0), p_10);
|
|
||||||
vstream(chi[ss+v]()(1)(1), p_11);
|
|
||||||
vstream(chi[ss+v]()(1)(2), p_12);
|
|
||||||
vstream(chi[ss+v]()(2)(0), p_20);
|
|
||||||
vstream(chi[ss+v]()(2)(1), p_21);
|
|
||||||
vstream(chi[ss+v]()(2)(2), p_22);
|
|
||||||
vstream(chi[ss+v]()(3)(0), p_30);
|
|
||||||
vstream(chi[ss+v]()(3)(1), p_31);
|
|
||||||
vstream(chi[ss+v]()(3)(2), p_32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper)
|
|
||||||
{
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
int nsimd = Simd::Nsimd();
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd>> u(LLs);
|
|
||||||
Vector<iSinglet<Simd>> l(LLs);
|
|
||||||
Vector<iSinglet<Simd>> 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; o<LLs; o++){ // outer
|
|
||||||
for(int i=0; i<nsimd; i++){ //inner
|
|
||||||
int s = o + i*LLs;
|
|
||||||
int ss = o*nsimd + i;
|
|
||||||
u_p[ss] = upper[s];
|
|
||||||
l_p[ss] = lower[s];
|
|
||||||
d_p[ss] = diag[s];
|
|
||||||
}}
|
|
||||||
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); 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<LLs; v++){
|
|
||||||
|
|
||||||
int vp = (v+1)%LLs;
|
|
||||||
int vm = (v+LLs-1)%LLs;
|
|
||||||
|
|
||||||
spProj5p(hp, psi[ss+vp]);
|
|
||||||
spProj5m(hm, psi[ss+vm]);
|
|
||||||
|
|
||||||
if(vp <= v){ rotate(hp, hp, 1); }
|
|
||||||
if(vm >= 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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
for(int v=0; v<LLs; v++){
|
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp = (v == LLs-1) ? 0 : v+1;
|
|
||||||
int vm = (v == 0 ) ? LLs-1 : v-1;
|
|
||||||
|
|
||||||
Simd hp_00 = psi[ss+vp]()(0)(0);
|
|
||||||
Simd hp_01 = psi[ss+vp]()(0)(1);
|
|
||||||
Simd hp_02 = psi[ss+vp]()(0)(2);
|
|
||||||
Simd hp_10 = psi[ss+vp]()(1)(0);
|
|
||||||
Simd hp_11 = psi[ss+vp]()(1)(1);
|
|
||||||
Simd hp_12 = psi[ss+vp]()(1)(2);
|
|
||||||
|
|
||||||
Simd hm_00 = psi[ss+vm]()(2)(0);
|
|
||||||
Simd hm_01 = psi[ss+vm]()(2)(1);
|
|
||||||
Simd hm_02 = psi[ss+vm]()(2)(2);
|
|
||||||
Simd hm_10 = psi[ss+vm]()(3)(0);
|
|
||||||
Simd hm_11 = psi[ss+vm]()(3)(1);
|
|
||||||
Simd hm_12 = psi[ss+vm]()(3)(2);
|
|
||||||
|
|
||||||
if (vp <= v){
|
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Simd p_00 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00);
|
|
||||||
Simd p_01 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01);
|
|
||||||
Simd p_02 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02);
|
|
||||||
Simd p_10 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10);
|
|
||||||
Simd p_11 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11);
|
|
||||||
Simd p_12 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12);
|
|
||||||
Simd p_20 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00);
|
|
||||||
Simd p_21 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01);
|
|
||||||
Simd p_22 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02);
|
|
||||||
Simd p_30 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10);
|
|
||||||
Simd p_31 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11);
|
|
||||||
Simd p_32 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12);
|
|
||||||
|
|
||||||
vstream(chi[ss+v]()(0)(0), p_00);
|
|
||||||
vstream(chi[ss+v]()(0)(1), p_01);
|
|
||||||
vstream(chi[ss+v]()(0)(2), p_02);
|
|
||||||
vstream(chi[ss+v]()(1)(0), p_10);
|
|
||||||
vstream(chi[ss+v]()(1)(1), p_11);
|
|
||||||
vstream(chi[ss+v]()(1)(2), p_12);
|
|
||||||
vstream(chi[ss+v]()(2)(0), p_20);
|
|
||||||
vstream(chi[ss+v]()(2)(1), p_21);
|
|
||||||
vstream(chi[ss+v]()(2)(2), p_22);
|
|
||||||
vstream(chi[ss+v]()(3)(0), p_30);
|
|
||||||
vstream(chi[ss+v]()(3)(1), p_31);
|
|
||||||
vstream(chi[ss+v]()(3)(2), p_32);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::M5Ddag_shift(const FermionField& psi, const FermionField& phi,
|
|
||||||
FermionField& chi, std::vector<Coeff_t>& lower, std::vector<Coeff_t>& diag, std::vector<Coeff_t>& upper,
|
|
||||||
std::vector<Coeff_t>& shift_coeffs)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
this->M5Ddag(psi, phi, chi, lower, diag, upper);
|
|
||||||
|
|
||||||
// FIXME: possible gain from vectorizing shift operation as well?
|
|
||||||
Coeff_t one(1.0);
|
|
||||||
int Ls = this->Ls;
|
|
||||||
for(int s=0; s<Ls; s++){
|
|
||||||
if(this->pm == 1){ axpby_ssp_pplus(chi, one, chi, shift_coeffs[s], psi, Ls-1, s); }
|
|
||||||
else{ axpby_ssp_pminus(chi, one, chi, shift_coeffs[s], psi, 0, s); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
GridBase* grid = psi._grid;
|
|
||||||
int Ls = this->Ls;
|
|
||||||
int LLs = grid->_rdimensions[0];
|
|
||||||
int nsimd = Simd::Nsimd();
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd>> u(LLs);
|
|
||||||
Vector<iSinglet<Simd>> l(LLs);
|
|
||||||
Vector<iSinglet<Simd>> d(LLs);
|
|
||||||
Vector<iSinglet<Simd>> s(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];
|
|
||||||
scalar_type* s_p = (scalar_type*) &s[0];
|
|
||||||
|
|
||||||
for(int o=0; o<LLs; o++){ // outer
|
|
||||||
for(int i=0; i<nsimd; i++){ //inner
|
|
||||||
int s = o + i*LLs;
|
|
||||||
int ss = o*nsimd + i;
|
|
||||||
u_p[ss] = upper[s];
|
|
||||||
l_p[ss] = lower[s];
|
|
||||||
d_p[ss] = diag[s];
|
|
||||||
s_p[ss] = shift_coeffs[s];
|
|
||||||
}}
|
|
||||||
|
|
||||||
this->M5Dcalls++;
|
|
||||||
this->M5Dtime -= usecond();
|
|
||||||
|
|
||||||
parallel_for(int ss=0; ss<grid->oSites(); ss+=LLs){ // adds LLs
|
|
||||||
|
|
||||||
int vs = (this->pm == 1) ? LLs-1 : 0;
|
|
||||||
Simd hs_00 = (this->pm == 1) ? psi[ss+vs]()(0)(0) : psi[ss+vs]()(2)(0);
|
|
||||||
Simd hs_01 = (this->pm == 1) ? psi[ss+vs]()(0)(1) : psi[ss+vs]()(2)(1);
|
|
||||||
Simd hs_02 = (this->pm == 1) ? psi[ss+vs]()(0)(2) : psi[ss+vs]()(2)(2);
|
|
||||||
Simd hs_10 = (this->pm == 1) ? psi[ss+vs]()(1)(0) : psi[ss+vs]()(3)(0);
|
|
||||||
Simd hs_11 = (this->pm == 1) ? psi[ss+vs]()(1)(1) : psi[ss+vs]()(3)(1);
|
|
||||||
Simd hs_12 = (this->pm == 1) ? psi[ss+vs]()(1)(2) : psi[ss+vs]()(3)(2);
|
|
||||||
|
|
||||||
for(int v=0; v<LLs; v++){
|
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp = (v == LLs-1) ? 0 : v+1;
|
|
||||||
int vm = (v == 0 ) ? LLs-1 : v-1;
|
|
||||||
|
|
||||||
Simd hp_00 = psi[ss+vp]()(0)(0);
|
|
||||||
Simd hp_01 = psi[ss+vp]()(0)(1);
|
|
||||||
Simd hp_02 = psi[ss+vp]()(0)(2);
|
|
||||||
Simd hp_10 = psi[ss+vp]()(1)(0);
|
|
||||||
Simd hp_11 = psi[ss+vp]()(1)(1);
|
|
||||||
Simd hp_12 = psi[ss+vp]()(1)(2);
|
|
||||||
|
|
||||||
Simd hm_00 = psi[ss+vm]()(2)(0);
|
|
||||||
Simd hm_01 = psi[ss+vm]()(2)(1);
|
|
||||||
Simd hm_02 = psi[ss+vm]()(2)(2);
|
|
||||||
Simd hm_10 = psi[ss+vm]()(3)(0);
|
|
||||||
Simd hm_11 = psi[ss+vm]()(3)(1);
|
|
||||||
Simd hm_12 = psi[ss+vm]()(3)(2);
|
|
||||||
|
|
||||||
if (vp <= v){
|
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(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(this->pm == 1 && vs <= v){
|
|
||||||
hs_00.v = Optimization::Rotate::tRotate<2>(hs_00.v);
|
|
||||||
hs_01.v = Optimization::Rotate::tRotate<2>(hs_01.v);
|
|
||||||
hs_02.v = Optimization::Rotate::tRotate<2>(hs_02.v);
|
|
||||||
hs_10.v = Optimization::Rotate::tRotate<2>(hs_10.v);
|
|
||||||
hs_11.v = Optimization::Rotate::tRotate<2>(hs_11.v);
|
|
||||||
hs_12.v = Optimization::Rotate::tRotate<2>(hs_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(this->pm == -1 && vs >= v){
|
|
||||||
hs_00.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_00.v);
|
|
||||||
hs_01.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_01.v);
|
|
||||||
hs_02.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_02.v);
|
|
||||||
hs_10.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_10.v);
|
|
||||||
hs_11.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_11.v);
|
|
||||||
hs_12.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hs_12.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
Simd p_00 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_00)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_00);
|
|
||||||
Simd p_01 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_01)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_01);
|
|
||||||
Simd p_02 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_02)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_02);
|
|
||||||
Simd p_10 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_10)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_10);
|
|
||||||
Simd p_11 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_11)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_11);
|
|
||||||
Simd p_12 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_12)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(), hp_12);
|
|
||||||
Simd p_20 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_00)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_00);
|
|
||||||
Simd p_21 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_01)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_01);
|
|
||||||
Simd p_22 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_02)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_02);
|
|
||||||
Simd p_30 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_10)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_10);
|
|
||||||
Simd p_31 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_11)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_11);
|
|
||||||
Simd p_32 = (this->pm == 1) ? switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12)
|
|
||||||
: switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(), hm_12)
|
|
||||||
+ switcheroo<Coeff_t>::mult(s[v]()()(), hs_12);
|
|
||||||
|
|
||||||
vstream(chi[ss+v]()(0)(0), p_00);
|
|
||||||
vstream(chi[ss+v]()(0)(1), p_01);
|
|
||||||
vstream(chi[ss+v]()(0)(2), p_02);
|
|
||||||
vstream(chi[ss+v]()(1)(0), p_10);
|
|
||||||
vstream(chi[ss+v]()(1)(1), p_11);
|
|
||||||
vstream(chi[ss+v]()(1)(2), p_12);
|
|
||||||
vstream(chi[ss+v]()(2)(0), p_20);
|
|
||||||
vstream(chi[ss+v]()(2)(1), p_21);
|
|
||||||
vstream(chi[ss+v]()(2)(2), p_22);
|
|
||||||
vstream(chi[ss+v]()(3)(0), p_30);
|
|
||||||
vstream(chi[ss+v]()(3)(1), p_31);
|
|
||||||
vstream(chi[ss+v]()(3)(2), p_32);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this->M5Dtime += usecond();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef AVX512
|
|
||||||
#include<simd/Intel512common.h>
|
|
||||||
#include<simd/Intel512avx.h>
|
|
||||||
#include<simd/Intel512single.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInternalAsm(const FermionField& psi, FermionField& chi,
|
|
||||||
int LLs, int site, Vector<iSinglet<Simd> >& Matp, Vector<iSinglet<Simd> >& Matm)
|
|
||||||
{
|
|
||||||
#ifndef AVX512
|
|
||||||
{
|
|
||||||
SiteHalfSpinor BcastP;
|
|
||||||
SiteHalfSpinor BcastM;
|
|
||||||
SiteHalfSpinor SiteChiP;
|
|
||||||
SiteHalfSpinor SiteChiM;
|
|
||||||
|
|
||||||
// Ls*Ls * 2 * 12 * vol flops
|
|
||||||
for(int s1=0; s1<LLs; s1++){
|
|
||||||
|
|
||||||
for(int s2=0; s2<LLs; s2++){
|
|
||||||
for(int l=0; l < Simd::Nsimd(); l++){ // simd lane
|
|
||||||
|
|
||||||
int s = s2 + l*LLs;
|
|
||||||
int lex = s2 + LLs*site;
|
|
||||||
|
|
||||||
if( s2==0 && l==0 ){
|
|
||||||
SiteChiP=zero;
|
|
||||||
SiteChiM=zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
vbroadcast(BcastP()(sp)(co), psi[lex]()(sp)(co), l);
|
|
||||||
}}
|
|
||||||
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
vbroadcast(BcastM()(sp)(co), psi[lex]()(sp+2)(co), l);
|
|
||||||
}}
|
|
||||||
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
SiteChiP()(sp)(co) = real_madd(Matp[LLs*s+s1]()()(), BcastP()(sp)(co), SiteChiP()(sp)(co)); // 1100 us.
|
|
||||||
SiteChiM()(sp)(co) = real_madd(Matm[LLs*s+s1]()()(), BcastM()(sp)(co), SiteChiM()(sp)(co)); // each found by commenting out
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
|
|
||||||
{
|
|
||||||
int lex = s1 + LLs*site;
|
|
||||||
for(int sp=0; sp<2; sp++){
|
|
||||||
for(int co=0; co<Nc; co++){
|
|
||||||
vstream(chi[lex]()(sp)(co), SiteChiP()(sp)(co));
|
|
||||||
vstream(chi[lex]()(sp+2)(co), SiteChiM()(sp)(co));
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
// pointers
|
|
||||||
// MASK_REGS;
|
|
||||||
#define Chi_00 %%zmm1
|
|
||||||
#define Chi_01 %%zmm2
|
|
||||||
#define Chi_02 %%zmm3
|
|
||||||
#define Chi_10 %%zmm4
|
|
||||||
#define Chi_11 %%zmm5
|
|
||||||
#define Chi_12 %%zmm6
|
|
||||||
#define Chi_20 %%zmm7
|
|
||||||
#define Chi_21 %%zmm8
|
|
||||||
#define Chi_22 %%zmm9
|
|
||||||
#define Chi_30 %%zmm10
|
|
||||||
#define Chi_31 %%zmm11
|
|
||||||
#define Chi_32 %%zmm12
|
|
||||||
|
|
||||||
#define BCAST0 %%zmm13
|
|
||||||
#define BCAST1 %%zmm14
|
|
||||||
#define BCAST2 %%zmm15
|
|
||||||
#define BCAST3 %%zmm16
|
|
||||||
#define BCAST4 %%zmm17
|
|
||||||
#define BCAST5 %%zmm18
|
|
||||||
#define BCAST6 %%zmm19
|
|
||||||
#define BCAST7 %%zmm20
|
|
||||||
#define BCAST8 %%zmm21
|
|
||||||
#define BCAST9 %%zmm22
|
|
||||||
#define BCAST10 %%zmm23
|
|
||||||
#define BCAST11 %%zmm24
|
|
||||||
|
|
||||||
int incr = LLs*LLs*sizeof(iSinglet<Simd>);
|
|
||||||
|
|
||||||
for(int s1=0; s1<LLs; s1++){
|
|
||||||
|
|
||||||
for(int s2=0; s2<LLs; s2++){
|
|
||||||
|
|
||||||
int lex = s2 + LLs*site;
|
|
||||||
uint64_t a0 = (uint64_t) &Matp[LLs*s2+s1]; // should be cacheable
|
|
||||||
uint64_t a1 = (uint64_t) &Matm[LLs*s2+s1];
|
|
||||||
uint64_t a2 = (uint64_t) &psi[lex];
|
|
||||||
|
|
||||||
for(int l=0; l<Simd::Nsimd(); l++){ // simd lane
|
|
||||||
|
|
||||||
if((s2+l)==0) {
|
|
||||||
asm(
|
|
||||||
VPREFETCH1(0,%2) VPREFETCH1(0,%1)
|
|
||||||
VPREFETCH1(12,%2) VPREFETCH1(13,%2)
|
|
||||||
VPREFETCH1(14,%2) VPREFETCH1(15,%2)
|
|
||||||
VBCASTCDUP(0,%2,BCAST0)
|
|
||||||
VBCASTCDUP(1,%2,BCAST1)
|
|
||||||
VBCASTCDUP(2,%2,BCAST2)
|
|
||||||
VBCASTCDUP(3,%2,BCAST3)
|
|
||||||
VBCASTCDUP(4,%2,BCAST4) VMULMEM(0,%0,BCAST0,Chi_00)
|
|
||||||
VBCASTCDUP(5,%2,BCAST5) VMULMEM(0,%0,BCAST1,Chi_01)
|
|
||||||
VBCASTCDUP(6,%2,BCAST6) VMULMEM(0,%0,BCAST2,Chi_02)
|
|
||||||
VBCASTCDUP(7,%2,BCAST7) VMULMEM(0,%0,BCAST3,Chi_10)
|
|
||||||
VBCASTCDUP(8,%2,BCAST8) VMULMEM(0,%0,BCAST4,Chi_11)
|
|
||||||
VBCASTCDUP(9,%2,BCAST9) VMULMEM(0,%0,BCAST5,Chi_12)
|
|
||||||
VBCASTCDUP(10,%2,BCAST10) VMULMEM(0,%1,BCAST6,Chi_20)
|
|
||||||
VBCASTCDUP(11,%2,BCAST11) VMULMEM(0,%1,BCAST7,Chi_21)
|
|
||||||
VMULMEM(0,%1,BCAST8,Chi_22)
|
|
||||||
VMULMEM(0,%1,BCAST9,Chi_30)
|
|
||||||
VMULMEM(0,%1,BCAST10,Chi_31)
|
|
||||||
VMULMEM(0,%1,BCAST11,Chi_32)
|
|
||||||
: : "r" (a0), "r" (a1), "r" (a2) );
|
|
||||||
} else {
|
|
||||||
asm(
|
|
||||||
VBCASTCDUP(0,%2,BCAST0) VMADDMEM(0,%0,BCAST0,Chi_00)
|
|
||||||
VBCASTCDUP(1,%2,BCAST1) VMADDMEM(0,%0,BCAST1,Chi_01)
|
|
||||||
VBCASTCDUP(2,%2,BCAST2) VMADDMEM(0,%0,BCAST2,Chi_02)
|
|
||||||
VBCASTCDUP(3,%2,BCAST3) VMADDMEM(0,%0,BCAST3,Chi_10)
|
|
||||||
VBCASTCDUP(4,%2,BCAST4) VMADDMEM(0,%0,BCAST4,Chi_11)
|
|
||||||
VBCASTCDUP(5,%2,BCAST5) VMADDMEM(0,%0,BCAST5,Chi_12)
|
|
||||||
VBCASTCDUP(6,%2,BCAST6) VMADDMEM(0,%1,BCAST6,Chi_20)
|
|
||||||
VBCASTCDUP(7,%2,BCAST7) VMADDMEM(0,%1,BCAST7,Chi_21)
|
|
||||||
VBCASTCDUP(8,%2,BCAST8) VMADDMEM(0,%1,BCAST8,Chi_22)
|
|
||||||
VBCASTCDUP(9,%2,BCAST9) VMADDMEM(0,%1,BCAST9,Chi_30)
|
|
||||||
VBCASTCDUP(10,%2,BCAST10) VMADDMEM(0,%1,BCAST10,Chi_31)
|
|
||||||
VBCASTCDUP(11,%2,BCAST11) VMADDMEM(0,%1,BCAST11,Chi_32)
|
|
||||||
: : "r" (a0), "r" (a1), "r" (a2) );
|
|
||||||
}
|
|
||||||
|
|
||||||
a0 = a0 + incr;
|
|
||||||
a1 = a1 + incr;
|
|
||||||
a2 = a2 + sizeof(Simd::scalar_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int lexa = s1+LLs*site;
|
|
||||||
asm (
|
|
||||||
VSTORE(0,%0,Chi_00) VSTORE(1 ,%0,Chi_01) VSTORE(2 ,%0,Chi_02)
|
|
||||||
VSTORE(3,%0,Chi_10) VSTORE(4 ,%0,Chi_11) VSTORE(5 ,%0,Chi_12)
|
|
||||||
VSTORE(6,%0,Chi_20) VSTORE(7 ,%0,Chi_21) VSTORE(8 ,%0,Chi_22)
|
|
||||||
VSTORE(9,%0,Chi_30) VSTORE(10,%0,Chi_31) VSTORE(11,%0,Chi_32)
|
|
||||||
: : "r" ((uint64_t)&chi[lexa]) : "memory" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef Chi_00
|
|
||||||
#undef Chi_01
|
|
||||||
#undef Chi_02
|
|
||||||
#undef Chi_10
|
|
||||||
#undef Chi_11
|
|
||||||
#undef Chi_12
|
|
||||||
#undef Chi_20
|
|
||||||
#undef Chi_21
|
|
||||||
#undef Chi_22
|
|
||||||
#undef Chi_30
|
|
||||||
#undef Chi_31
|
|
||||||
#undef Chi_32
|
|
||||||
|
|
||||||
#undef BCAST0
|
|
||||||
#undef BCAST1
|
|
||||||
#undef BCAST2
|
|
||||||
#undef BCAST3
|
|
||||||
#undef BCAST4
|
|
||||||
#undef BCAST5
|
|
||||||
#undef BCAST6
|
|
||||||
#undef BCAST7
|
|
||||||
#undef BCAST8
|
|
||||||
#undef BCAST9
|
|
||||||
#undef BCAST10
|
|
||||||
#undef BCAST11
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// Z-mobius version
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::MooeeInternalZAsm(const FermionField& psi, FermionField& chi,
|
|
||||||
int LLs, int site, Vector<iSinglet<Simd> >& Matp, Vector<iSinglet<Simd> >& Matm)
|
|
||||||
{
|
|
||||||
std::cout << "Error: zMobius not implemented for EOFA" << std::endl;
|
|
||||||
exit(-1);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
void MobiusEOFAFermion<Impl>::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;
|
|
||||||
|
|
||||||
Vector<iSinglet<Simd>> Matp;
|
|
||||||
Vector<iSinglet<Simd>> Matm;
|
|
||||||
Vector<iSinglet<Simd>>* _Matp;
|
|
||||||
Vector<iSinglet<Simd>>* _Matm;
|
|
||||||
|
|
||||||
// MooeeInternalCompute(dag,inv,Matp,Matm);
|
|
||||||
if(inv && dag){
|
|
||||||
_Matp = &this->MatpInvDag;
|
|
||||||
_Matm = &this->MatmInvDag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(inv && (!dag)){
|
|
||||||
_Matp = &this->MatpInv;
|
|
||||||
_Matm = &this->MatmInv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!inv){
|
|
||||||
MooeeInternalCompute(dag, inv, Matp, Matm);
|
|
||||||
_Matp = &Matp;
|
|
||||||
_Matm = &Matm;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(_Matp->size() == Ls*LLs);
|
|
||||||
|
|
||||||
this->MooeeInvCalls++;
|
|
||||||
this->MooeeInvTime -= usecond();
|
|
||||||
|
|
||||||
if(switcheroo<Coeff_t>::iscomplex()){
|
|
||||||
parallel_for(auto site=0; site<vol; site++){
|
|
||||||
MooeeInternalZAsm(psi, chi, LLs, site, *_Matp, *_Matm);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parallel_for(auto site=0; site<vol; site++){
|
|
||||||
MooeeInternalAsm(psi, chi, LLs, site, *_Matp, *_Matm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->MooeeInvTime += usecond();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MOBIUS_EOFA_DPERP_VEC
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(DomainWallVec5dImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(DomainWallVec5dImplF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZDomainWallVec5dImplD);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZDomainWallVec5dImplF);
|
|
||||||
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(DomainWallVec5dImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(DomainWallVec5dImplFH);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZDomainWallVec5dImplDF);
|
|
||||||
INSTANTIATE_DPERP_MOBIUS_EOFA(ZDomainWallVec5dImplFH);
|
|
||||||
|
|
||||||
template void MobiusEOFAFermion<DomainWallVec5dImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<DomainWallVec5dImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZDomainWallVec5dImplF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZDomainWallVec5dImplD>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
template void MobiusEOFAFermion<DomainWallVec5dImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<DomainWallVec5dImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZDomainWallVec5dImplFH>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
template void MobiusEOFAFermion<ZDomainWallVec5dImplDF>::MooeeInternal(const FermionField& psi, FermionField& chi, int dag, int inv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -30,147 +30,33 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
|
|
||||||
#define REGISTER
|
#define REGISTER
|
||||||
|
|
||||||
#define LOAD_CHIMU_BODY(F) \
|
#define LOAD_CHIMU \
|
||||||
Chimu_00=ref(F)(0)(0); \
|
|
||||||
Chimu_01=ref(F)(0)(1); \
|
|
||||||
Chimu_02=ref(F)(0)(2); \
|
|
||||||
Chimu_10=ref(F)(1)(0); \
|
|
||||||
Chimu_11=ref(F)(1)(1); \
|
|
||||||
Chimu_12=ref(F)(1)(2); \
|
|
||||||
Chimu_20=ref(F)(2)(0); \
|
|
||||||
Chimu_21=ref(F)(2)(1); \
|
|
||||||
Chimu_22=ref(F)(2)(2); \
|
|
||||||
Chimu_30=ref(F)(3)(0); \
|
|
||||||
Chimu_31=ref(F)(3)(1); \
|
|
||||||
Chimu_32=ref(F)(3)(2)
|
|
||||||
|
|
||||||
#define LOAD_CHIMU(DIR,F,PERM) \
|
|
||||||
{ const SiteSpinor & ref (in._odata[offset]); LOAD_CHIMU_BODY(F); }
|
|
||||||
|
|
||||||
#define LOAD_CHI_BODY(F) \
|
|
||||||
Chi_00 = ref(F)(0)(0);\
|
|
||||||
Chi_01 = ref(F)(0)(1);\
|
|
||||||
Chi_02 = ref(F)(0)(2);\
|
|
||||||
Chi_10 = ref(F)(1)(0);\
|
|
||||||
Chi_11 = ref(F)(1)(1);\
|
|
||||||
Chi_12 = ref(F)(1)(2)
|
|
||||||
|
|
||||||
#define LOAD_CHI(DIR,F,PERM) \
|
|
||||||
{const SiteHalfSpinor &ref(buf[offset]); LOAD_CHI_BODY(F); }
|
|
||||||
|
|
||||||
|
|
||||||
//G-parity implementations using in-place intrinsic ops
|
|
||||||
|
|
||||||
//1l 1h -> 1h 1l
|
|
||||||
//0l 0h , 1h 1l -> 0l 1h 0h,1l
|
|
||||||
//0h,1l -> 1l,0h
|
|
||||||
//if( (distance == 1 && !perm_will_occur) || (distance == -1 && perm_will_occur) )
|
|
||||||
//Pulled fermion through forwards face, GPBC on upper component
|
|
||||||
//Need 0= 0l 1h 1= 1l 0h
|
|
||||||
//else if( (distance == -1 && !perm) || (distance == 1 && perm) )
|
|
||||||
//Pulled fermion through backwards face, GPBC on lower component
|
|
||||||
//Need 0= 1l 0h 1= 0l 1h
|
|
||||||
|
|
||||||
//1l 1h -> 1h 1l
|
|
||||||
//0l 0h , 1h 1l -> 0l 1h 0h,1l
|
|
||||||
#define DO_TWIST_0L_1H(INTO,S,C,F, PERM, tmp1, tmp2, tmp3) \
|
|
||||||
permute##PERM(tmp1, ref(1)(S)(C)); \
|
|
||||||
exchange##PERM(tmp2,tmp3, ref(0)(S)(C), tmp1); \
|
|
||||||
INTO = tmp2;
|
|
||||||
|
|
||||||
//0l 0h -> 0h 0l
|
|
||||||
//1l 1h, 0h 0l -> 1l 0h, 1h 0l
|
|
||||||
#define DO_TWIST_1L_0H(INTO,S,C,F, PERM, tmp1, tmp2, tmp3) \
|
|
||||||
permute##PERM(tmp1, ref(0)(S)(C)); \
|
|
||||||
exchange##PERM(tmp2,tmp3, ref(1)(S)(C), tmp1); \
|
|
||||||
INTO = tmp2;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define LOAD_CHI_SETUP(DIR,F) \
|
|
||||||
g = F; \
|
|
||||||
direction = st._directions[DIR]; \
|
|
||||||
distance = st._distances[DIR]; \
|
|
||||||
sl = st._grid->_simd_layout[direction]; \
|
|
||||||
inplace_twist = 0; \
|
|
||||||
if(SE->_around_the_world && this->Params.twists[DIR % 4]){ \
|
|
||||||
if(sl == 1){ \
|
|
||||||
g = (F+1) % 2; \
|
|
||||||
}else{ \
|
|
||||||
inplace_twist = 1; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOAD_CHIMU_GPARITY_INPLACE_TWIST(DIR,F,PERM) \
|
|
||||||
{const SiteSpinor & ref (in._odata[offset]); \
|
{const SiteSpinor & ref (in._odata[offset]); \
|
||||||
LOAD_CHI_SETUP(DIR,F); \
|
Chimu_00=ref()(0)(0);\
|
||||||
if(!inplace_twist){ \
|
Chimu_01=ref()(0)(1);\
|
||||||
LOAD_CHIMU_BODY(g); \
|
Chimu_02=ref()(0)(2);\
|
||||||
}else{ \
|
Chimu_10=ref()(1)(0);\
|
||||||
if( ( F==0 && ((distance == 1 && !perm) || (distance == -1 && perm)) ) || \
|
Chimu_11=ref()(1)(1);\
|
||||||
( F==1 && ((distance == -1 && !perm) || (distance == 1 && perm)) ) ){ \
|
Chimu_12=ref()(1)(2);\
|
||||||
DO_TWIST_0L_1H(Chimu_00,0,0,F,PERM, U_00,U_01,U_10); \
|
Chimu_20=ref()(2)(0);\
|
||||||
DO_TWIST_0L_1H(Chimu_01,0,1,F,PERM, U_11,U_20,U_21); \
|
Chimu_21=ref()(2)(1);\
|
||||||
DO_TWIST_0L_1H(Chimu_02,0,2,F,PERM, U_00,U_01,U_10); \
|
Chimu_22=ref()(2)(2);\
|
||||||
DO_TWIST_0L_1H(Chimu_10,1,0,F,PERM, U_11,U_20,U_21); \
|
Chimu_30=ref()(3)(0);\
|
||||||
DO_TWIST_0L_1H(Chimu_11,1,1,F,PERM, U_00,U_01,U_10); \
|
Chimu_31=ref()(3)(1);\
|
||||||
DO_TWIST_0L_1H(Chimu_12,1,2,F,PERM, U_11,U_20,U_21); \
|
Chimu_32=ref()(3)(2);}
|
||||||
DO_TWIST_0L_1H(Chimu_20,2,0,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_0L_1H(Chimu_21,2,1,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_0L_1H(Chimu_22,2,2,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_0L_1H(Chimu_30,3,0,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_0L_1H(Chimu_31,3,1,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_0L_1H(Chimu_32,3,2,F,PERM, U_11,U_20,U_21); \
|
|
||||||
}else{ \
|
|
||||||
DO_TWIST_1L_0H(Chimu_00,0,0,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_01,0,1,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_02,0,2,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_10,1,0,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_11,1,1,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_12,1,2,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_20,2,0,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_21,2,1,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_22,2,2,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_30,3,0,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_31,3,1,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chimu_32,3,2,F,PERM, U_11,U_20,U_21); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#define LOAD_CHI\
|
||||||
#define LOAD_CHI_GPARITY_INPLACE_TWIST(DIR,F,PERM) \
|
|
||||||
{const SiteHalfSpinor &ref(buf[offset]); \
|
{const SiteHalfSpinor &ref(buf[offset]); \
|
||||||
LOAD_CHI_SETUP(DIR,F); \
|
Chi_00 = ref()(0)(0);\
|
||||||
if(!inplace_twist){ \
|
Chi_01 = ref()(0)(1);\
|
||||||
LOAD_CHI_BODY(g); \
|
Chi_02 = ref()(0)(2);\
|
||||||
}else{ \
|
Chi_10 = ref()(1)(0);\
|
||||||
if( ( F==0 && ((distance == 1 && !perm) || (distance == -1 && perm)) ) || \
|
Chi_11 = ref()(1)(1);\
|
||||||
( F==1 && ((distance == -1 && !perm) || (distance == 1 && perm)) ) ){ \
|
Chi_12 = ref()(1)(2);}
|
||||||
DO_TWIST_0L_1H(Chi_00,0,0,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_0L_1H(Chi_01,0,1,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_0L_1H(Chi_02,0,2,F,PERM, UChi_00,UChi_01,UChi_02); \
|
|
||||||
DO_TWIST_0L_1H(Chi_10,1,0,F,PERM, UChi_10,UChi_11,UChi_12); \
|
|
||||||
DO_TWIST_0L_1H(Chi_11,1,1,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_0L_1H(Chi_12,1,2,F,PERM, U_11,U_20,U_21); \
|
|
||||||
}else{ \
|
|
||||||
DO_TWIST_1L_0H(Chi_00,0,0,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chi_01,0,1,F,PERM, U_11,U_20,U_21); \
|
|
||||||
DO_TWIST_1L_0H(Chi_02,0,2,F,PERM, UChi_00,UChi_01,UChi_02); \
|
|
||||||
DO_TWIST_1L_0H(Chi_10,1,0,F,PERM, UChi_10,UChi_11,UChi_12); \
|
|
||||||
DO_TWIST_1L_0H(Chi_11,1,1,F,PERM, U_00,U_01,U_10); \
|
|
||||||
DO_TWIST_1L_0H(Chi_12,1,2,F,PERM, U_11,U_20,U_21); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define LOAD_CHI_GPARITY(DIR,F,PERM) LOAD_CHI_GPARITY_INPLACE_TWIST(DIR,F,PERM)
|
|
||||||
#define LOAD_CHIMU_GPARITY(DIR,F,PERM) LOAD_CHIMU_GPARITY_INPLACE_TWIST(DIR,F,PERM)
|
|
||||||
|
|
||||||
// To splat or not to splat depends on the implementation
|
// To splat or not to splat depends on the implementation
|
||||||
#define MULT_2SPIN_BODY \
|
#define MULT_2SPIN(A)\
|
||||||
|
{auto & ref(U._odata[sU](A)); \
|
||||||
Impl::loadLinkElement(U_00,ref()(0,0)); \
|
Impl::loadLinkElement(U_00,ref()(0,0)); \
|
||||||
Impl::loadLinkElement(U_10,ref()(1,0)); \
|
Impl::loadLinkElement(U_10,ref()(1,0)); \
|
||||||
Impl::loadLinkElement(U_20,ref()(2,0)); \
|
Impl::loadLinkElement(U_20,ref()(2,0)); \
|
||||||
@@ -197,14 +83,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
UChi_01+= U_10*Chi_02;\
|
UChi_01+= U_10*Chi_02;\
|
||||||
UChi_11+= U_10*Chi_12;\
|
UChi_11+= U_10*Chi_12;\
|
||||||
UChi_02+= U_20*Chi_02;\
|
UChi_02+= U_20*Chi_02;\
|
||||||
UChi_12+= U_20*Chi_12
|
UChi_12+= U_20*Chi_12;}
|
||||||
|
|
||||||
|
|
||||||
#define MULT_2SPIN(A,F) \
|
|
||||||
{auto & ref(U._odata[sU](A)); MULT_2SPIN_BODY; }
|
|
||||||
|
|
||||||
#define MULT_2SPIN_GPARITY(A,F) \
|
|
||||||
{auto & ref(U._odata[sU](F)(A)); MULT_2SPIN_BODY; }
|
|
||||||
|
|
||||||
|
|
||||||
#define PERMUTE_DIR(dir) \
|
#define PERMUTE_DIR(dir) \
|
||||||
@@ -428,87 +307,84 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
result_31-= UChi_11; \
|
result_31-= UChi_11; \
|
||||||
result_32-= UChi_12;
|
result_32-= UChi_12;
|
||||||
|
|
||||||
#define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
#define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON) \
|
||||||
SE=st.GetEntry(ptype,DIR,ss); \
|
SE=st.GetEntry(ptype,DIR,ss); \
|
||||||
offset = SE->_offset; \
|
offset = SE->_offset; \
|
||||||
local = SE->_is_local; \
|
local = SE->_is_local; \
|
||||||
perm = SE->_permute; \
|
perm = SE->_permute; \
|
||||||
if ( local ) { \
|
if ( local ) { \
|
||||||
LOAD_CHIMU_IMPL(DIR,F,PERM); \
|
LOAD_CHIMU; \
|
||||||
PROJ; \
|
PROJ; \
|
||||||
if ( perm) { \
|
if ( perm) { \
|
||||||
PERMUTE_DIR(PERM); \
|
PERMUTE_DIR(PERM); \
|
||||||
} \
|
} \
|
||||||
} else { \
|
} else { \
|
||||||
LOAD_CHI_IMPL(DIR,F,PERM); \
|
LOAD_CHI; \
|
||||||
} \
|
} \
|
||||||
MULT_2SPIN_IMPL(DIR,F); \
|
MULT_2SPIN(DIR); \
|
||||||
RECON;
|
RECON;
|
||||||
|
|
||||||
|
#define HAND_STENCIL_LEG_INT(PROJ,PERM,DIR,RECON) \
|
||||||
#define HAND_STENCIL_LEG_INT(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
|
||||||
SE=st.GetEntry(ptype,DIR,ss); \
|
SE=st.GetEntry(ptype,DIR,ss); \
|
||||||
offset = SE->_offset; \
|
offset = SE->_offset; \
|
||||||
local = SE->_is_local; \
|
local = SE->_is_local; \
|
||||||
perm = SE->_permute; \
|
perm = SE->_permute; \
|
||||||
if ( local ) { \
|
if ( local ) { \
|
||||||
LOAD_CHIMU_IMPL(DIR,F,PERM); \
|
LOAD_CHIMU; \
|
||||||
PROJ; \
|
PROJ; \
|
||||||
if ( perm) { \
|
if ( perm) { \
|
||||||
PERMUTE_DIR(PERM); \
|
PERMUTE_DIR(PERM); \
|
||||||
} \
|
} \
|
||||||
} else if ( st.same_node[DIR] ) { \
|
} else if ( st.same_node[DIR] ) { \
|
||||||
LOAD_CHI_IMPL(DIR,F,PERM); \
|
LOAD_CHI; \
|
||||||
} \
|
} \
|
||||||
if (local || st.same_node[DIR] ) { \
|
if (local || st.same_node[DIR] ) { \
|
||||||
MULT_2SPIN_IMPL(DIR,F); \
|
MULT_2SPIN(DIR); \
|
||||||
RECON; \
|
RECON; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
#define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON) \
|
||||||
SE=st.GetEntry(ptype,DIR,ss); \
|
SE=st.GetEntry(ptype,DIR,ss); \
|
||||||
offset = SE->_offset; \
|
offset = SE->_offset; \
|
||||||
local = SE->_is_local; \
|
|
||||||
perm = SE->_permute; \
|
|
||||||
if((!SE->_is_local)&&(!st.same_node[DIR]) ) { \
|
if((!SE->_is_local)&&(!st.same_node[DIR]) ) { \
|
||||||
LOAD_CHI_IMPL(DIR,F,PERM); \
|
LOAD_CHI; \
|
||||||
MULT_2SPIN_IMPL(DIR,F); \
|
MULT_2SPIN(DIR); \
|
||||||
RECON; \
|
RECON; \
|
||||||
nmu++; \
|
nmu++; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAND_RESULT(ss,F) \
|
#define HAND_RESULT(ss) \
|
||||||
{ \
|
{ \
|
||||||
SiteSpinor & ref (out._odata[ss]); \
|
SiteSpinor & ref (out._odata[ss]); \
|
||||||
vstream(ref(F)(0)(0),result_00); \
|
vstream(ref()(0)(0),result_00); \
|
||||||
vstream(ref(F)(0)(1),result_01); \
|
vstream(ref()(0)(1),result_01); \
|
||||||
vstream(ref(F)(0)(2),result_02); \
|
vstream(ref()(0)(2),result_02); \
|
||||||
vstream(ref(F)(1)(0),result_10); \
|
vstream(ref()(1)(0),result_10); \
|
||||||
vstream(ref(F)(1)(1),result_11); \
|
vstream(ref()(1)(1),result_11); \
|
||||||
vstream(ref(F)(1)(2),result_12); \
|
vstream(ref()(1)(2),result_12); \
|
||||||
vstream(ref(F)(2)(0),result_20); \
|
vstream(ref()(2)(0),result_20); \
|
||||||
vstream(ref(F)(2)(1),result_21); \
|
vstream(ref()(2)(1),result_21); \
|
||||||
vstream(ref(F)(2)(2),result_22); \
|
vstream(ref()(2)(2),result_22); \
|
||||||
vstream(ref(F)(3)(0),result_30); \
|
vstream(ref()(3)(0),result_30); \
|
||||||
vstream(ref(F)(3)(1),result_31); \
|
vstream(ref()(3)(1),result_31); \
|
||||||
vstream(ref(F)(3)(2),result_32); \
|
vstream(ref()(3)(2),result_32); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAND_RESULT_EXT(ss,F) \
|
#define HAND_RESULT_EXT(ss) \
|
||||||
if (nmu){ \
|
if (nmu){ \
|
||||||
SiteSpinor & ref (out._odata[ss]); \
|
SiteSpinor & ref (out._odata[ss]); \
|
||||||
ref(F)(0)(0)+=result_00; \
|
ref()(0)(0)+=result_00; \
|
||||||
ref(F)(0)(1)+=result_01; \
|
ref()(0)(1)+=result_01; \
|
||||||
ref(F)(0)(2)+=result_02; \
|
ref()(0)(2)+=result_02; \
|
||||||
ref(F)(1)(0)+=result_10; \
|
ref()(1)(0)+=result_10; \
|
||||||
ref(F)(1)(1)+=result_11; \
|
ref()(1)(1)+=result_11; \
|
||||||
ref(F)(1)(2)+=result_12; \
|
ref()(1)(2)+=result_12; \
|
||||||
ref(F)(2)(0)+=result_20; \
|
ref()(2)(0)+=result_20; \
|
||||||
ref(F)(2)(1)+=result_21; \
|
ref()(2)(1)+=result_21; \
|
||||||
ref(F)(2)(2)+=result_22; \
|
ref()(2)(2)+=result_22; \
|
||||||
ref(F)(3)(0)+=result_30; \
|
ref()(3)(0)+=result_30; \
|
||||||
ref(F)(3)(1)+=result_31; \
|
ref()(3)(1)+=result_31; \
|
||||||
ref(F)(3)(2)+=result_32; \
|
ref()(3)(2)+=result_32; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -587,18 +463,15 @@ WilsonKernels<Impl>::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGauge
|
|||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
|
|
||||||
#define HAND_DOP_SITE(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
HAND_STENCIL_LEG(XM_PROJ,3,Xp,XM_RECON);
|
||||||
HAND_STENCIL_LEG(XM_PROJ,3,Xp,XM_RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(YM_PROJ,2,Yp,YM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(ZM_PROJ,1,Zp,ZM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(TM_PROJ,0,Tp,TM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(XP_PROJ,3,Xm,XP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(YP_PROJ,2,Ym,YP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(ZP_PROJ,1,Zm,ZP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(TP_PROJ,0,Tm,TP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_RESULT(ss);
|
||||||
HAND_RESULT(ss,F)
|
|
||||||
|
|
||||||
HAND_DOP_SITE(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
@@ -613,18 +486,15 @@ void WilsonKernels<Impl>::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,Doub
|
|||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
|
|
||||||
#define HAND_DOP_SITE_DAG(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
HAND_STENCIL_LEG(XP_PROJ,3,Xp,XP_RECON);
|
||||||
HAND_STENCIL_LEG(XP_PROJ,3,Xp,XP_RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(YP_PROJ,2,Yp,YP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(ZP_PROJ,1,Zp,ZP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(TP_PROJ,0,Tp,TP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(XM_PROJ,3,Xm,XM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(YM_PROJ,2,Ym,YM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(ZM_PROJ,1,Zm,ZM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG(TM_PROJ,0,Tm,TM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_RESULT(ss);
|
||||||
HAND_RESULT(ss,F)
|
|
||||||
|
|
||||||
HAND_DOP_SITE_DAG(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl> void
|
template<class Impl> void
|
||||||
@@ -639,20 +509,16 @@ WilsonKernels<Impl>::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGa
|
|||||||
|
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
|
ZERO_RESULT;
|
||||||
#define HAND_DOP_SITE_INT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
HAND_STENCIL_LEG_INT(XM_PROJ,3,Xp,XM_RECON_ACCUM);
|
||||||
ZERO_RESULT; \
|
HAND_STENCIL_LEG_INT(YM_PROJ,2,Yp,YM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(XM_PROJ,3,Xp,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(TM_PROJ,0,Tp,TM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(XP_PROJ,3,Xm,XP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(YP_PROJ,2,Ym,YP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(TP_PROJ,0,Tm,TP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_RESULT(ss);
|
||||||
HAND_STENCIL_LEG_INT(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
|
||||||
HAND_RESULT(ss,F)
|
|
||||||
|
|
||||||
HAND_DOP_SITE_INT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
@@ -666,20 +532,16 @@ void WilsonKernels<Impl>::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,D
|
|||||||
|
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
|
ZERO_RESULT;
|
||||||
#define HAND_DOP_SITE_DAG_INT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
HAND_STENCIL_LEG_INT(XP_PROJ,3,Xp,XP_RECON_ACCUM);
|
||||||
ZERO_RESULT; \
|
HAND_STENCIL_LEG_INT(YP_PROJ,2,Yp,YP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(XP_PROJ,3,Xp,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(TP_PROJ,0,Tp,TP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(XM_PROJ,3,Xm,XM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(YM_PROJ,2,Ym,YM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_INT(TM_PROJ,0,Tm,TM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_RESULT(ss);
|
||||||
HAND_STENCIL_LEG_INT(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
|
||||||
HAND_RESULT(ss,F)
|
|
||||||
|
|
||||||
HAND_DOP_SITE_DAG_INT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl> void
|
template<class Impl> void
|
||||||
@@ -695,20 +557,16 @@ WilsonKernels<Impl>::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGa
|
|||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int nmu=0;
|
int nmu=0;
|
||||||
|
ZERO_RESULT;
|
||||||
#define HAND_DOP_SITE_EXT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xp,XM_RECON_ACCUM);
|
||||||
ZERO_RESULT; \
|
HAND_STENCIL_LEG_EXT(YM_PROJ,2,Yp,YM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xp,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tp,TM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xm,XP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(YP_PROJ,2,Ym,YP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tm,TP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_RESULT_EXT(ss);
|
||||||
HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
|
||||||
HAND_RESULT_EXT(ss,F)
|
|
||||||
|
|
||||||
HAND_DOP_SITE_EXT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
@@ -723,20 +581,16 @@ void WilsonKernels<Impl>::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,D
|
|||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
int nmu=0;
|
int nmu=0;
|
||||||
|
ZERO_RESULT;
|
||||||
#define HAND_DOP_SITE_DAG_EXT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \
|
HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xp,XP_RECON_ACCUM);
|
||||||
ZERO_RESULT; \
|
HAND_STENCIL_LEG_EXT(YP_PROJ,2,Yp,YP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xp,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tp,TP_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xm,XM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(YM_PROJ,2,Ym,YM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tm,TM_RECON_ACCUM);
|
||||||
HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
HAND_RESULT_EXT(ss);
|
||||||
HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \
|
|
||||||
HAND_RESULT_EXT(ss,F)
|
|
||||||
|
|
||||||
HAND_DOP_SITE_DAG_EXT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
@@ -792,123 +646,10 @@ void WilsonKernels<Impl>::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,D
|
|||||||
const FermionField &in, \
|
const FermionField &in, \
|
||||||
FermionField &out){ assert(0); } \
|
FermionField &out){ assert(0); } \
|
||||||
|
|
||||||
|
HAND_SPECIALISE_EMPTY(GparityWilsonImplF);
|
||||||
|
HAND_SPECIALISE_EMPTY(GparityWilsonImplD);
|
||||||
#define HAND_SPECIALISE_GPARITY(IMPL) \
|
HAND_SPECIALISE_EMPTY(GparityWilsonImplFH);
|
||||||
template<> void \
|
HAND_SPECIALISE_EMPTY(GparityWilsonImplDF);
|
||||||
WilsonKernels<IMPL>::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \
|
|
||||||
int ss,int sU,const FermionField &in, FermionField &out) \
|
|
||||||
{ \
|
|
||||||
typedef IMPL Impl; \
|
|
||||||
typedef typename Simd::scalar_type S; \
|
|
||||||
typedef typename Simd::vector_type V; \
|
|
||||||
\
|
|
||||||
HAND_DECLARATIONS(ignore); \
|
|
||||||
\
|
|
||||||
int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \
|
|
||||||
StencilEntry *SE; \
|
|
||||||
HAND_DOP_SITE(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
HAND_DOP_SITE(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
template<> \
|
|
||||||
void WilsonKernels<IMPL>::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \
|
|
||||||
int ss,int sU,const FermionField &in, FermionField &out) \
|
|
||||||
{ \
|
|
||||||
typedef IMPL Impl; \
|
|
||||||
typedef typename Simd::scalar_type S; \
|
|
||||||
typedef typename Simd::vector_type V; \
|
|
||||||
\
|
|
||||||
HAND_DECLARATIONS(ignore); \
|
|
||||||
\
|
|
||||||
StencilEntry *SE; \
|
|
||||||
int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \
|
|
||||||
HAND_DOP_SITE_DAG(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
HAND_DOP_SITE_DAG(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
template<> void \
|
|
||||||
WilsonKernels<IMPL>::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \
|
|
||||||
int ss,int sU,const FermionField &in, FermionField &out) \
|
|
||||||
{ \
|
|
||||||
typedef IMPL Impl; \
|
|
||||||
typedef typename Simd::scalar_type S; \
|
|
||||||
typedef typename Simd::vector_type V; \
|
|
||||||
\
|
|
||||||
HAND_DECLARATIONS(ignore); \
|
|
||||||
\
|
|
||||||
int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \
|
|
||||||
StencilEntry *SE; \
|
|
||||||
HAND_DOP_SITE_INT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
HAND_DOP_SITE_INT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
template<> \
|
|
||||||
void WilsonKernels<IMPL>::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \
|
|
||||||
int ss,int sU,const FermionField &in, FermionField &out) \
|
|
||||||
{ \
|
|
||||||
typedef IMPL Impl; \
|
|
||||||
typedef typename Simd::scalar_type S; \
|
|
||||||
typedef typename Simd::vector_type V; \
|
|
||||||
\
|
|
||||||
HAND_DECLARATIONS(ignore); \
|
|
||||||
\
|
|
||||||
StencilEntry *SE; \
|
|
||||||
int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \
|
|
||||||
HAND_DOP_SITE_DAG_INT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
HAND_DOP_SITE_DAG_INT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
template<> void \
|
|
||||||
WilsonKernels<IMPL>::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \
|
|
||||||
int ss,int sU,const FermionField &in, FermionField &out) \
|
|
||||||
{ \
|
|
||||||
typedef IMPL Impl; \
|
|
||||||
typedef typename Simd::scalar_type S; \
|
|
||||||
typedef typename Simd::vector_type V; \
|
|
||||||
\
|
|
||||||
HAND_DECLARATIONS(ignore); \
|
|
||||||
\
|
|
||||||
int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \
|
|
||||||
StencilEntry *SE; \
|
|
||||||
int nmu=0; \
|
|
||||||
HAND_DOP_SITE_EXT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
nmu = 0; \
|
|
||||||
HAND_DOP_SITE_EXT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
} \
|
|
||||||
template<> \
|
|
||||||
void WilsonKernels<IMPL>::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \
|
|
||||||
int ss,int sU,const FermionField &in, FermionField &out) \
|
|
||||||
{ \
|
|
||||||
typedef IMPL Impl; \
|
|
||||||
typedef typename Simd::scalar_type S; \
|
|
||||||
typedef typename Simd::vector_type V; \
|
|
||||||
\
|
|
||||||
HAND_DECLARATIONS(ignore); \
|
|
||||||
\
|
|
||||||
StencilEntry *SE; \
|
|
||||||
int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \
|
|
||||||
int nmu=0; \
|
|
||||||
HAND_DOP_SITE_DAG_EXT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
nmu = 0; \
|
|
||||||
HAND_DOP_SITE_DAG_EXT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HAND_SPECIALISE_GPARITY(GparityWilsonImplF);
|
|
||||||
HAND_SPECIALISE_GPARITY(GparityWilsonImplD);
|
|
||||||
HAND_SPECIALISE_GPARITY(GparityWilsonImplFH);
|
|
||||||
HAND_SPECIALISE_GPARITY(GparityWilsonImplDF);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////// Wilson ; uses this implementation /////////////////////
|
////////////// Wilson ; uses this implementation /////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace Grid{
|
|||||||
// (Moe Moo) (Moe Mee^-1 1 ) (0 Moo-Moe Mee^-1 Meo) (0 1 )
|
// (Moe Moo) (Moe Mee^-1 1 ) (0 Moo-Moe Mee^-1 Meo) (0 1 )
|
||||||
//
|
//
|
||||||
// Determinant is det of middle factor
|
// Determinant is det of middle factor
|
||||||
// NOTICE: This assumes Mee is indept of U in computing the derivative
|
// This assumes Mee is indept of U.
|
||||||
//
|
//
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
class SchurDifferentiableOperator : public SchurDiagMooeeOperator<FermionOperator<Impl>,typename Impl::FermionField>
|
class SchurDifferentiableOperator : public SchurDiagMooeeOperator<FermionOperator<Impl>,typename Impl::FermionField>
|
||||||
|
|||||||
@@ -1,264 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/pseudofermion/ExactOneFlavourRatio.h
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
|
||||||
// Implementation of exact one flavour algorithm (EOFA) //
|
|
||||||
// using fermion classes defined in: //
|
|
||||||
// Grid/qcd/action/fermion/DomainWallEOFAFermion.h (Shamir) //
|
|
||||||
// Grid/qcd/action/fermion/MobiusEOFAFermion.h (Mobius) //
|
|
||||||
// arXiv: 1403.1683, 1706.05843 //
|
|
||||||
/////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
|
|
||||||
#define QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
|
|
||||||
|
|
||||||
namespace Grid{
|
|
||||||
namespace QCD{
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////
|
|
||||||
// Exact one flavour implementation of DWF determinant ratio //
|
|
||||||
///////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<class Impl>
|
|
||||||
class ExactOneFlavourRatioPseudoFermionAction : public Action<typename Impl::GaugeField>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
INHERIT_IMPL_TYPES(Impl);
|
|
||||||
typedef OneFlavourRationalParams Params;
|
|
||||||
Params param;
|
|
||||||
MultiShiftFunction PowerNegHalf;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool use_heatbath_forecasting;
|
|
||||||
AbstractEOFAFermion<Impl>& Lop; // the basic LH operator
|
|
||||||
AbstractEOFAFermion<Impl>& Rop; // the basic RH operator
|
|
||||||
SchurRedBlackDiagMooeeSolve<FermionField> Solver;
|
|
||||||
FermionField Phi; // the pseudofermion field for this trajectory
|
|
||||||
|
|
||||||
public:
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction(AbstractEOFAFermion<Impl>& _Lop, AbstractEOFAFermion<Impl>& _Rop,
|
|
||||||
OperatorFunction<FermionField>& S, Params& p, bool use_fc=false) : Lop(_Lop), Rop(_Rop), Solver(S),
|
|
||||||
Phi(_Lop.FermionGrid()), param(p), use_heatbath_forecasting(use_fc)
|
|
||||||
{
|
|
||||||
AlgRemez remez(param.lo, param.hi, param.precision);
|
|
||||||
|
|
||||||
// MdagM^(+- 1/2)
|
|
||||||
std::cout << GridLogMessage << "Generating degree " << param.degree << " for x^(-1/2)" << std::endl;
|
|
||||||
remez.generateApprox(param.degree, 1, 2);
|
|
||||||
PowerNegHalf.Init(remez, param.tolerance, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual std::string action_name() { return "ExactOneFlavourRatioPseudoFermionAction"; }
|
|
||||||
|
|
||||||
virtual std::string LogParameters() {
|
|
||||||
std::stringstream sstream;
|
|
||||||
sstream << GridLogMessage << "[" << action_name() << "] Low :" << param.lo << std::endl;
|
|
||||||
sstream << GridLogMessage << "[" << action_name() << "] High :" << param.hi << std::endl;
|
|
||||||
sstream << GridLogMessage << "[" << action_name() << "] Max iterations :" << param.MaxIter << std::endl;
|
|
||||||
sstream << GridLogMessage << "[" << action_name() << "] Tolerance :" << param.tolerance << std::endl;
|
|
||||||
sstream << GridLogMessage << "[" << action_name() << "] Degree :" << param.degree << std::endl;
|
|
||||||
sstream << GridLogMessage << "[" << action_name() << "] Precision :" << param.precision << std::endl;
|
|
||||||
return sstream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spin projection
|
|
||||||
void spProj(const FermionField& in, FermionField& out, int sign, int Ls)
|
|
||||||
{
|
|
||||||
if(sign == 1){ for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(out, 0.0, in, 1.0, in, s, s); } }
|
|
||||||
else{ for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(out, 0.0, in, 1.0, in, s, s); } }
|
|
||||||
}
|
|
||||||
|
|
||||||
// EOFA heatbath: see Eqn. (29) of arXiv:1706.05843
|
|
||||||
// We generate a Gaussian noise vector \eta, and then compute
|
|
||||||
// \Phi = M_{\rm EOFA}^{-1/2} * \eta
|
|
||||||
// using a rational approximation to the inverse square root
|
|
||||||
virtual void refresh(const GaugeField& U, GridParallelRNG& pRNG)
|
|
||||||
{
|
|
||||||
Lop.ImportGauge(U);
|
|
||||||
Rop.ImportGauge(U);
|
|
||||||
|
|
||||||
FermionField eta (Lop.FermionGrid());
|
|
||||||
FermionField CG_src (Lop.FermionGrid());
|
|
||||||
FermionField CG_soln (Lop.FermionGrid());
|
|
||||||
FermionField Forecast_src(Lop.FermionGrid());
|
|
||||||
std::vector<FermionField> tmp(2, Lop.FermionGrid());
|
|
||||||
|
|
||||||
// Use chronological inverter to forecast solutions across poles
|
|
||||||
std::vector<FermionField> prev_solns;
|
|
||||||
if(use_heatbath_forecasting){ prev_solns.reserve(param.degree); }
|
|
||||||
ChronoForecast<AbstractEOFAFermion<Impl>, FermionField> Forecast;
|
|
||||||
|
|
||||||
// Seed with Gaussian noise vector (var = 0.5)
|
|
||||||
RealD scale = std::sqrt(0.5);
|
|
||||||
gaussian(pRNG,eta);
|
|
||||||
eta = eta * scale;
|
|
||||||
printf("Heatbath source vector: <\\eta|\\eta> = %1.15e\n", norm2(eta));
|
|
||||||
|
|
||||||
// \Phi = ( \alpha_{0} + \sum_{k=1}^{N_{p}} \alpha_{l} * \gamma_{l} ) * \eta
|
|
||||||
RealD N(PowerNegHalf.norm);
|
|
||||||
for(int k=0; k<param.degree; ++k){ N += PowerNegHalf.residues[k] / ( 1.0 + PowerNegHalf.poles[k] ); }
|
|
||||||
Phi = eta * N;
|
|
||||||
|
|
||||||
// LH terms:
|
|
||||||
// \Phi = \Phi + k \sum_{k=1}^{N_{p}} P_{-} \Omega_{-}^{\dagger} ( H(mf)
|
|
||||||
// - \gamma_{l} \Delta_{-}(mf,mb) P_{-} )^{-1} \Omega_{-} P_{-} \eta
|
|
||||||
RealD gamma_l(0.0);
|
|
||||||
spProj(eta, tmp[0], -1, Lop.Ls);
|
|
||||||
Lop.Omega(tmp[0], tmp[1], -1, 0);
|
|
||||||
G5R5(CG_src, tmp[1]);
|
|
||||||
tmp[1] = zero;
|
|
||||||
for(int k=0; k<param.degree; ++k){
|
|
||||||
gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] );
|
|
||||||
Lop.RefreshShiftCoefficients(-gamma_l);
|
|
||||||
if(use_heatbath_forecasting){ // Forecast CG guess using solutions from previous poles
|
|
||||||
Lop.Mdag(CG_src, Forecast_src);
|
|
||||||
CG_soln = Forecast(Lop, Forecast_src, prev_solns);
|
|
||||||
Solver(Lop, CG_src, CG_soln);
|
|
||||||
prev_solns.push_back(CG_soln);
|
|
||||||
} else {
|
|
||||||
CG_soln = zero; // Just use zero as the initial guess
|
|
||||||
Solver(Lop, CG_src, CG_soln);
|
|
||||||
}
|
|
||||||
Lop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
|
|
||||||
tmp[1] = tmp[1] + ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Lop.k ) * tmp[0];
|
|
||||||
}
|
|
||||||
Lop.Omega(tmp[1], tmp[0], -1, 1);
|
|
||||||
spProj(tmp[0], tmp[1], -1, Lop.Ls);
|
|
||||||
Phi = Phi + tmp[1];
|
|
||||||
|
|
||||||
// RH terms:
|
|
||||||
// \Phi = \Phi - k \sum_{k=1}^{N_{p}} P_{+} \Omega_{+}^{\dagger} ( H(mb)
|
|
||||||
// + \gamma_{l} \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \eta
|
|
||||||
spProj(eta, tmp[0], 1, Rop.Ls);
|
|
||||||
Rop.Omega(tmp[0], tmp[1], 1, 0);
|
|
||||||
G5R5(CG_src, tmp[1]);
|
|
||||||
tmp[1] = zero;
|
|
||||||
if(use_heatbath_forecasting){ prev_solns.clear(); } // empirically, LH solns don't help for RH solves
|
|
||||||
for(int k=0; k<param.degree; ++k){
|
|
||||||
gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] );
|
|
||||||
Rop.RefreshShiftCoefficients(-gamma_l*PowerNegHalf.poles[k]);
|
|
||||||
if(use_heatbath_forecasting){
|
|
||||||
Rop.Mdag(CG_src, Forecast_src);
|
|
||||||
CG_soln = Forecast(Rop, Forecast_src, prev_solns);
|
|
||||||
Solver(Rop, CG_src, CG_soln);
|
|
||||||
prev_solns.push_back(CG_soln);
|
|
||||||
} else {
|
|
||||||
CG_soln = zero;
|
|
||||||
Solver(Rop, CG_src, CG_soln);
|
|
||||||
}
|
|
||||||
Rop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
|
|
||||||
tmp[1] = tmp[1] - ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Rop.k ) * tmp[0];
|
|
||||||
}
|
|
||||||
Rop.Omega(tmp[1], tmp[0], 1, 1);
|
|
||||||
spProj(tmp[0], tmp[1], 1, Rop.Ls);
|
|
||||||
Phi = Phi + tmp[1];
|
|
||||||
|
|
||||||
// Reset shift coefficients for energy and force evals
|
|
||||||
Lop.RefreshShiftCoefficients(0.0);
|
|
||||||
Rop.RefreshShiftCoefficients(-1.0);
|
|
||||||
};
|
|
||||||
|
|
||||||
// EOFA action: see Eqn. (10) of arXiv:1706.05843
|
|
||||||
virtual RealD S(const GaugeField& U)
|
|
||||||
{
|
|
||||||
Lop.ImportGauge(U);
|
|
||||||
Rop.ImportGauge(U);
|
|
||||||
|
|
||||||
FermionField spProj_Phi(Lop.FermionGrid());
|
|
||||||
std::vector<FermionField> tmp(2, Lop.FermionGrid());
|
|
||||||
|
|
||||||
// S = <\Phi|\Phi>
|
|
||||||
RealD action(norm2(Phi));
|
|
||||||
|
|
||||||
// LH term: S = S - k <\Phi| P_{-} \Omega_{-}^{\dagger} H(mf)^{-1} \Omega_{-} P_{-} |\Phi>
|
|
||||||
spProj(Phi, spProj_Phi, -1, Lop.Ls);
|
|
||||||
Lop.Omega(spProj_Phi, tmp[0], -1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
Solver(Lop, tmp[1], tmp[0]);
|
|
||||||
Lop.Dtilde(tmp[0], tmp[1]); // We actually solved Cayley preconditioned system: transform back
|
|
||||||
Lop.Omega(tmp[1], tmp[0], -1, 1);
|
|
||||||
action -= Lop.k * innerProduct(spProj_Phi, tmp[0]).real();
|
|
||||||
|
|
||||||
// RH term: S = S + k <\Phi| P_{+} \Omega_{+}^{\dagger} ( H(mb)
|
|
||||||
// - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{-} P_{-} |\Phi>
|
|
||||||
spProj(Phi, spProj_Phi, 1, Rop.Ls);
|
|
||||||
Rop.Omega(spProj_Phi, tmp[0], 1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
Solver(Rop, tmp[1], tmp[0]);
|
|
||||||
Rop.Dtilde(tmp[0], tmp[1]);
|
|
||||||
Rop.Omega(tmp[1], tmp[0], 1, 1);
|
|
||||||
action += Rop.k * innerProduct(spProj_Phi, tmp[0]).real();
|
|
||||||
|
|
||||||
return action;
|
|
||||||
};
|
|
||||||
|
|
||||||
// EOFA pseudofermion force: see Eqns. (34)-(36) of arXiv:1706.05843
|
|
||||||
virtual void deriv(const GaugeField& U, GaugeField& dSdU)
|
|
||||||
{
|
|
||||||
Lop.ImportGauge(U);
|
|
||||||
Rop.ImportGauge(U);
|
|
||||||
|
|
||||||
FermionField spProj_Phi (Lop.FermionGrid());
|
|
||||||
FermionField Omega_spProj_Phi(Lop.FermionGrid());
|
|
||||||
FermionField CG_src (Lop.FermionGrid());
|
|
||||||
FermionField Chi (Lop.FermionGrid());
|
|
||||||
FermionField g5_R5_Chi (Lop.FermionGrid());
|
|
||||||
|
|
||||||
GaugeField force(Lop.GaugeGrid());
|
|
||||||
|
|
||||||
// LH: dSdU = k \chi_{L}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{L}
|
|
||||||
// \chi_{L} = H(mf)^{-1} \Omega_{-} P_{-} \Phi
|
|
||||||
spProj(Phi, spProj_Phi, -1, Lop.Ls);
|
|
||||||
Lop.Omega(spProj_Phi, Omega_spProj_Phi, -1, 0);
|
|
||||||
G5R5(CG_src, Omega_spProj_Phi);
|
|
||||||
spProj_Phi = zero;
|
|
||||||
Solver(Lop, CG_src, spProj_Phi);
|
|
||||||
Lop.Dtilde(spProj_Phi, Chi);
|
|
||||||
G5R5(g5_R5_Chi, Chi);
|
|
||||||
Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo);
|
|
||||||
dSdU = Lop.k * force;
|
|
||||||
|
|
||||||
// RH: dSdU = dSdU - k \chi_{R}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{}
|
|
||||||
// \chi_{R} = ( H(mb) - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \Phi
|
|
||||||
spProj(Phi, spProj_Phi, 1, Rop.Ls);
|
|
||||||
Rop.Omega(spProj_Phi, Omega_spProj_Phi, 1, 0);
|
|
||||||
G5R5(CG_src, Omega_spProj_Phi);
|
|
||||||
spProj_Phi = zero;
|
|
||||||
Solver(Rop, CG_src, spProj_Phi);
|
|
||||||
Rop.Dtilde(spProj_Phi, Chi);
|
|
||||||
G5R5(g5_R5_Chi, Chi);
|
|
||||||
Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo);
|
|
||||||
dSdU = dSdU - Rop.k * force;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -38,6 +38,5 @@ directory
|
|||||||
#include <Grid/qcd/action/pseudofermion/OneFlavourRationalRatio.h>
|
#include <Grid/qcd/action/pseudofermion/OneFlavourRationalRatio.h>
|
||||||
#include <Grid/qcd/action/pseudofermion/OneFlavourEvenOddRational.h>
|
#include <Grid/qcd/action/pseudofermion/OneFlavourEvenOddRational.h>
|
||||||
#include <Grid/qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h>
|
#include <Grid/qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h>
|
||||||
#include <Grid/qcd/action/pseudofermion/ExactOneFlavourRatio.h>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -202,39 +202,6 @@ class DomainWallFermionModule: public FermionOperatorModule<DomainWallFermion, F
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DomainWallEOFAFermionParameters : Serializable {
|
|
||||||
public:
|
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(DomainWallEOFAFermionParameters,
|
|
||||||
RealD, mq1,
|
|
||||||
RealD, mq2,
|
|
||||||
RealD, mq3,
|
|
||||||
RealD, shift,
|
|
||||||
int, pm,
|
|
||||||
RealD, M5,
|
|
||||||
unsigned int, Ls);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class FermionImpl >
|
|
||||||
class DomainWallEOFAFermionModule: public FermionOperatorModule<DomainWallEOFAFermion, FermionImpl, DomainWallEOFAFermionParameters> {
|
|
||||||
typedef FermionOperatorModule<DomainWallEOFAFermion, FermionImpl, DomainWallEOFAFermionParameters> FermBase;
|
|
||||||
using FermBase::FermBase; // for constructors
|
|
||||||
|
|
||||||
virtual unsigned int Ls(){
|
|
||||||
return this->Par_.Ls;
|
|
||||||
}
|
|
||||||
|
|
||||||
// acquire resource
|
|
||||||
virtual void initialize(){
|
|
||||||
auto GridMod = this->GridRefs[0];
|
|
||||||
auto GridMod5d = this->GridRefs[1];
|
|
||||||
typename FermionImpl::GaugeField U(GridMod->get_full());
|
|
||||||
this->FOPtr.reset(new DomainWallEOFAFermion<FermionImpl>( U, *(GridMod->get_full()), *(GridMod->get_rb()),
|
|
||||||
*(GridMod5d->get_full()), *(GridMod5d->get_rb()),
|
|
||||||
this->Par_.mq1, this->Par_.mq2, this->Par_.mq3,
|
|
||||||
this->Par_.shift, this->Par_.pm, this->Par_.M5));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // QCD
|
} // QCD
|
||||||
} // Grid
|
} // Grid
|
||||||
|
|||||||
@@ -1,209 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./lib/qcd/action/scalar/CovariantAdjointLaplacian.h
|
|
||||||
|
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Guido Cossu <guido.cossu@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 COVARIANT_ADJOINT_LAPLACIAN_H
|
|
||||||
#define COVARIANT_ADJOINT_LAPLACIAN_H
|
|
||||||
|
|
||||||
namespace Grid
|
|
||||||
{
|
|
||||||
namespace QCD
|
|
||||||
{
|
|
||||||
|
|
||||||
struct LaplacianParams : Serializable
|
|
||||||
{
|
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LaplacianParams,
|
|
||||||
RealD, lo,
|
|
||||||
RealD, hi,
|
|
||||||
int, MaxIter,
|
|
||||||
RealD, tolerance,
|
|
||||||
int, degree,
|
|
||||||
int, precision);
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
LaplacianParams(RealD lo = 0.0,
|
|
||||||
RealD hi = 1.0,
|
|
||||||
int maxit = 1000,
|
|
||||||
RealD tol = 1.0e-8,
|
|
||||||
int degree = 10,
|
|
||||||
int precision = 64)
|
|
||||||
: lo(lo),
|
|
||||||
hi(hi),
|
|
||||||
MaxIter(maxit),
|
|
||||||
tolerance(tol),
|
|
||||||
degree(degree),
|
|
||||||
precision(precision){};
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Laplacian operator L on adjoint fields
|
|
||||||
//
|
|
||||||
// phi: adjoint field
|
|
||||||
// L: D_mu^dag D_mu
|
|
||||||
//
|
|
||||||
// L phi(x) = Sum_mu [ U_mu(x)phi(x+mu)U_mu(x)^dag +
|
|
||||||
// U_mu(x-mu)^dag phi(x-mu)U_mu(x-mu)
|
|
||||||
// -2phi(x)]
|
|
||||||
//
|
|
||||||
// Operator designed to be encapsulated by
|
|
||||||
// an HermitianLinearOperator<.. , ..>
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Impl>
|
|
||||||
class LaplacianAdjointField : public Metric<typename Impl::Field>
|
|
||||||
{
|
|
||||||
OperatorFunction<typename Impl::Field> &Solver;
|
|
||||||
LaplacianParams param;
|
|
||||||
MultiShiftFunction PowerHalf;
|
|
||||||
MultiShiftFunction PowerInvHalf;
|
|
||||||
|
|
||||||
public:
|
|
||||||
INHERIT_GIMPL_TYPES(Impl);
|
|
||||||
|
|
||||||
LaplacianAdjointField(GridBase *grid, OperatorFunction<GaugeField> &S, LaplacianParams &p, const RealD k = 1.0)
|
|
||||||
: U(Nd, grid), Solver(S), param(p), kappa(k)
|
|
||||||
{
|
|
||||||
AlgRemez remez(param.lo, param.hi, param.precision);
|
|
||||||
std::cout << GridLogMessage << "Generating degree " << param.degree << " for x^(1/2)" << std::endl;
|
|
||||||
remez.generateApprox(param.degree, 1, 2);
|
|
||||||
PowerHalf.Init(remez, param.tolerance, false);
|
|
||||||
PowerInvHalf.Init(remez, param.tolerance, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
void Mdir(const GaugeField &, GaugeField &, int, int) { assert(0); }
|
|
||||||
void Mdiag(const GaugeField &, GaugeField &) { assert(0); }
|
|
||||||
|
|
||||||
void ImportGauge(const GaugeField &_U)
|
|
||||||
{
|
|
||||||
for (int mu = 0; mu < Nd; mu++)
|
|
||||||
{
|
|
||||||
U[mu] = PeekIndex<LorentzIndex>(_U, mu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void M(const GaugeField &in, GaugeField &out)
|
|
||||||
{
|
|
||||||
// in is an antihermitian matrix
|
|
||||||
// test
|
|
||||||
//GaugeField herm = in + adj(in);
|
|
||||||
//std::cout << "AHermiticity: " << norm2(herm) << std::endl;
|
|
||||||
|
|
||||||
GaugeLinkField tmp(in._grid);
|
|
||||||
GaugeLinkField tmp2(in._grid);
|
|
||||||
GaugeLinkField sum(in._grid);
|
|
||||||
|
|
||||||
for (int nu = 0; nu < Nd; nu++)
|
|
||||||
{
|
|
||||||
sum = zero;
|
|
||||||
GaugeLinkField in_nu = PeekIndex<LorentzIndex>(in, nu);
|
|
||||||
GaugeLinkField out_nu(out._grid);
|
|
||||||
for (int mu = 0; mu < Nd; mu++)
|
|
||||||
{
|
|
||||||
tmp = U[mu] * Cshift(in_nu, mu, +1) * adj(U[mu]);
|
|
||||||
tmp2 = adj(U[mu]) * in_nu * U[mu];
|
|
||||||
sum += tmp + Cshift(tmp2, mu, -1) - 2.0 * in_nu;
|
|
||||||
}
|
|
||||||
out_nu = (1.0 - kappa) * in_nu - kappa / (double(4 * Nd)) * sum;
|
|
||||||
PokeIndex<LorentzIndex>(out, out_nu, nu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MDeriv(const GaugeField &in, GaugeField &der)
|
|
||||||
{
|
|
||||||
// in is anti-hermitian
|
|
||||||
RealD factor = -kappa / (double(4 * Nd));
|
|
||||||
|
|
||||||
for (int mu = 0; mu < Nd; mu++)
|
|
||||||
{
|
|
||||||
GaugeLinkField der_mu(der._grid);
|
|
||||||
der_mu = zero;
|
|
||||||
for (int nu = 0; nu < Nd; nu++)
|
|
||||||
{
|
|
||||||
GaugeLinkField in_nu = PeekIndex<LorentzIndex>(in, nu);
|
|
||||||
der_mu += U[mu] * Cshift(in_nu, mu, 1) * adj(U[mu]) * in_nu;
|
|
||||||
}
|
|
||||||
// the minus sign comes by using the in_nu instead of the
|
|
||||||
// adjoint in the last multiplication
|
|
||||||
PokeIndex<LorentzIndex>(der, -2.0 * factor * der_mu, mu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// separating this temporarily
|
|
||||||
void MDeriv(const GaugeField &left, const GaugeField &right,
|
|
||||||
GaugeField &der)
|
|
||||||
{
|
|
||||||
// in is anti-hermitian
|
|
||||||
RealD factor = -kappa / (double(4 * Nd));
|
|
||||||
|
|
||||||
for (int mu = 0; mu < Nd; mu++)
|
|
||||||
{
|
|
||||||
GaugeLinkField der_mu(der._grid);
|
|
||||||
der_mu = zero;
|
|
||||||
for (int nu = 0; nu < Nd; nu++)
|
|
||||||
{
|
|
||||||
GaugeLinkField left_nu = PeekIndex<LorentzIndex>(left, nu);
|
|
||||||
GaugeLinkField right_nu = PeekIndex<LorentzIndex>(right, nu);
|
|
||||||
der_mu += U[mu] * Cshift(left_nu, mu, 1) * adj(U[mu]) * right_nu;
|
|
||||||
der_mu += U[mu] * Cshift(right_nu, mu, 1) * adj(U[mu]) * left_nu;
|
|
||||||
}
|
|
||||||
PokeIndex<LorentzIndex>(der, -factor * der_mu, mu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Minv(const GaugeField &in, GaugeField &inverted)
|
|
||||||
{
|
|
||||||
HermitianLinearOperator<LaplacianAdjointField<Impl>, GaugeField> HermOp(*this);
|
|
||||||
Solver(HermOp, in, inverted);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MSquareRoot(GaugeField &P)
|
|
||||||
{
|
|
||||||
GaugeField Gp(P._grid);
|
|
||||||
HermitianLinearOperator<LaplacianAdjointField<Impl>, GaugeField> HermOp(*this);
|
|
||||||
ConjugateGradientMultiShift<GaugeField> msCG(param.MaxIter, PowerHalf);
|
|
||||||
msCG(HermOp, P, Gp);
|
|
||||||
P = Gp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MInvSquareRoot(GaugeField &P)
|
|
||||||
{
|
|
||||||
GaugeField Gp(P._grid);
|
|
||||||
HermitianLinearOperator<LaplacianAdjointField<Impl>, GaugeField> HermOp(*this);
|
|
||||||
ConjugateGradientMultiShift<GaugeField> msCG(param.MaxIter, PowerInvHalf);
|
|
||||||
msCG(HermOp, P, Gp);
|
|
||||||
P = Gp;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RealD kappa;
|
|
||||||
std::vector<GaugeLinkField> U;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // QCD
|
|
||||||
} // Grid
|
|
||||||
#endif
|
|
||||||
@@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: ./lib/qcd/action/scalar/CovariantLaplacian.h
|
Source file: ./lib/qcd/action/scalar/CovariantLaplacian.h
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2016
|
||||||
|
|
||||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
||||||
|
|
||||||
@@ -30,57 +30,168 @@ directory
|
|||||||
#ifndef COVARIANT_LAPLACIAN_H
|
#ifndef COVARIANT_LAPLACIAN_H
|
||||||
#define COVARIANT_LAPLACIAN_H
|
#define COVARIANT_LAPLACIAN_H
|
||||||
|
|
||||||
namespace Grid
|
namespace Grid {
|
||||||
{
|
namespace QCD {
|
||||||
namespace QCD
|
|
||||||
{
|
struct LaplacianParams : Serializable {
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LaplacianParams,
|
||||||
|
RealD, lo,
|
||||||
|
RealD, hi,
|
||||||
|
int, MaxIter,
|
||||||
|
RealD, tolerance,
|
||||||
|
int, degree,
|
||||||
|
int, precision);
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
LaplacianParams(RealD lo = 0.0,
|
||||||
|
RealD hi = 1.0,
|
||||||
|
int maxit = 1000,
|
||||||
|
RealD tol = 1.0e-8,
|
||||||
|
int degree = 10,
|
||||||
|
int precision = 64)
|
||||||
|
: lo(lo),
|
||||||
|
hi(hi),
|
||||||
|
MaxIter(maxit),
|
||||||
|
tolerance(tol),
|
||||||
|
degree(degree),
|
||||||
|
precision(precision){};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Laplacian operator L on fermion fields
|
// Laplacian operator L on adjoint fields
|
||||||
//
|
//
|
||||||
// phi: fermion field
|
// phi: adjoint field
|
||||||
|
// L: D_mu^dag D_mu
|
||||||
//
|
//
|
||||||
// L phi(x) = Sum_mu [ U_mu(x) phi(x+mu) + U_mu(x-mu) phi(x-mu) - 2phi(x)]
|
// L phi(x) = Sum_mu [ U_mu(x)phi(x+mu)U_mu(x)^dag +
|
||||||
|
// U_mu(x-mu)^dag phi(x-mu)U_mu(x-mu)
|
||||||
|
// -2phi(x)]
|
||||||
//
|
//
|
||||||
// Operator designed to be encapsulated by
|
// Operator designed to be encapsulated by
|
||||||
// an HermitianLinearOperator<.. , ..>
|
// an HermitianLinearOperator<.. , ..>
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// has to inherit from a fermion implementation
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
class Laplacian
|
class LaplacianAdjointField: public Metric<typename Impl::Field> {
|
||||||
{
|
OperatorFunction<typename Impl::Field> &Solver;
|
||||||
|
LaplacianParams param;
|
||||||
|
MultiShiftFunction PowerHalf;
|
||||||
|
MultiShiftFunction PowerInvHalf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
INHERIT_IMPL_TYPES(Impl);
|
INHERIT_GIMPL_TYPES(Impl);
|
||||||
|
|
||||||
// add a bool to smear only in the spatial directions
|
LaplacianAdjointField(GridBase* grid, OperatorFunction<GaugeField>& S, LaplacianParams& p, const RealD k = 1.0)
|
||||||
Laplacian(GridBase *grid, bool spatial = false)
|
: U(Nd, grid), Solver(S), param(p), kappa(k){
|
||||||
: U(Nd, grid), spatial_laplacian(spatial){};
|
AlgRemez remez(param.lo,param.hi,param.precision);
|
||||||
|
std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/2)"<<std::endl;
|
||||||
|
remez.generateApprox(param.degree,1,2);
|
||||||
|
PowerHalf.Init(remez,param.tolerance,false);
|
||||||
|
PowerInvHalf.Init(remez,param.tolerance,true);
|
||||||
|
|
||||||
void Mdir(const FermionField &, FermionField &, int, int) { assert(0); }
|
|
||||||
void Mdiag(const FermionField &, FermionField &) { assert(0); }
|
|
||||||
|
|
||||||
void ImportGauge(const GaugeField &_U)
|
};
|
||||||
{
|
|
||||||
for (int mu = 0; mu < Nd; mu++)
|
void Mdir(const GaugeField&, GaugeField&, int, int){ assert(0);}
|
||||||
|
void Mdiag(const GaugeField&, GaugeField&){ assert(0);}
|
||||||
|
|
||||||
|
void ImportGauge(const GaugeField& _U) {
|
||||||
|
for (int mu = 0; mu < Nd; mu++) {
|
||||||
U[mu] = PeekIndex<LorentzIndex>(_U, mu);
|
U[mu] = PeekIndex<LorentzIndex>(_U, mu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void M(const FermionField &in, FermionField &out)
|
|
||||||
{
|
|
||||||
int dims = spatial_laplacian ? (Nd - 1) : Nd;
|
|
||||||
|
|
||||||
out = -2.0 * dims * in;
|
|
||||||
// eventually speed up with the stencil operator, if necessary
|
|
||||||
for (int mu = 0; mu < dims; mu++)
|
|
||||||
out += Impl::CovShiftForward(U[mu], mu, in) + Impl::CovShiftBackward(U[mu], mu, in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void M(const GaugeField& in, GaugeField& out) {
|
||||||
bool spatial_laplacian;
|
// in is an antihermitian matrix
|
||||||
std::vector<GaugeLinkField> U;
|
// test
|
||||||
}; // Laplacian
|
//GaugeField herm = in + adj(in);
|
||||||
|
//std::cout << "AHermiticity: " << norm2(herm) << std::endl;
|
||||||
|
|
||||||
|
GaugeLinkField tmp(in._grid);
|
||||||
|
GaugeLinkField tmp2(in._grid);
|
||||||
|
GaugeLinkField sum(in._grid);
|
||||||
|
|
||||||
|
for (int nu = 0; nu < Nd; nu++) {
|
||||||
|
sum = zero;
|
||||||
|
GaugeLinkField in_nu = PeekIndex<LorentzIndex>(in, nu);
|
||||||
|
GaugeLinkField out_nu(out._grid);
|
||||||
|
for (int mu = 0; mu < Nd; mu++) {
|
||||||
|
tmp = U[mu] * Cshift(in_nu, mu, +1) * adj(U[mu]);
|
||||||
|
tmp2 = adj(U[mu]) * in_nu * U[mu];
|
||||||
|
sum += tmp + Cshift(tmp2, mu, -1) - 2.0 * in_nu;
|
||||||
|
}
|
||||||
|
out_nu = (1.0 - kappa) * in_nu - kappa / (double(4 * Nd)) * sum;
|
||||||
|
PokeIndex<LorentzIndex>(out, out_nu, nu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDeriv(const GaugeField& in, GaugeField& der) {
|
||||||
|
// in is anti-hermitian
|
||||||
|
RealD factor = -kappa / (double(4 * Nd));
|
||||||
|
|
||||||
|
for (int mu = 0; mu < Nd; mu++){
|
||||||
|
GaugeLinkField der_mu(der._grid);
|
||||||
|
der_mu = zero;
|
||||||
|
for (int nu = 0; nu < Nd; nu++){
|
||||||
|
GaugeLinkField in_nu = PeekIndex<LorentzIndex>(in, nu);
|
||||||
|
der_mu += U[mu] * Cshift(in_nu, mu, 1) * adj(U[mu]) * in_nu;
|
||||||
|
}
|
||||||
|
// the minus sign comes by using the in_nu instead of the
|
||||||
|
// adjoint in the last multiplication
|
||||||
|
PokeIndex<LorentzIndex>(der, -2.0 * factor * der_mu, mu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// separating this temporarily
|
||||||
|
void MDeriv(const GaugeField& left, const GaugeField& right,
|
||||||
|
GaugeField& der) {
|
||||||
|
// in is anti-hermitian
|
||||||
|
RealD factor = -kappa / (double(4 * Nd));
|
||||||
|
|
||||||
|
for (int mu = 0; mu < Nd; mu++) {
|
||||||
|
GaugeLinkField der_mu(der._grid);
|
||||||
|
der_mu = zero;
|
||||||
|
for (int nu = 0; nu < Nd; nu++) {
|
||||||
|
GaugeLinkField left_nu = PeekIndex<LorentzIndex>(left, nu);
|
||||||
|
GaugeLinkField right_nu = PeekIndex<LorentzIndex>(right, nu);
|
||||||
|
der_mu += U[mu] * Cshift(left_nu, mu, 1) * adj(U[mu]) * right_nu;
|
||||||
|
der_mu += U[mu] * Cshift(right_nu, mu, 1) * adj(U[mu]) * left_nu;
|
||||||
|
}
|
||||||
|
PokeIndex<LorentzIndex>(der, -factor * der_mu, mu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Minv(const GaugeField& in, GaugeField& inverted){
|
||||||
|
HermitianLinearOperator<LaplacianAdjointField<Impl>,GaugeField> HermOp(*this);
|
||||||
|
Solver(HermOp, in, inverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MSquareRoot(GaugeField& P){
|
||||||
|
GaugeField Gp(P._grid);
|
||||||
|
HermitianLinearOperator<LaplacianAdjointField<Impl>,GaugeField> HermOp(*this);
|
||||||
|
ConjugateGradientMultiShift<GaugeField> msCG(param.MaxIter,PowerHalf);
|
||||||
|
msCG(HermOp,P,Gp);
|
||||||
|
P = Gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MInvSquareRoot(GaugeField& P){
|
||||||
|
GaugeField Gp(P._grid);
|
||||||
|
HermitianLinearOperator<LaplacianAdjointField<Impl>,GaugeField> HermOp(*this);
|
||||||
|
ConjugateGradientMultiShift<GaugeField> msCG(param.MaxIter,PowerInvHalf);
|
||||||
|
msCG(HermOp,P,Gp);
|
||||||
|
P = Gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
RealD kappa;
|
||||||
|
std::vector<GaugeLinkField> U;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // QCD
|
|
||||||
} // Grid
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ GridCartesian *SpaceTimeGrid::makeFiveDimGrid(int Ls,const GridCartesian
|
|||||||
simd5.push_back(FourDimGrid->_simd_layout[d]);
|
simd5.push_back(FourDimGrid->_simd_layout[d]);
|
||||||
mpi5.push_back(FourDimGrid->_processors[d]);
|
mpi5.push_back(FourDimGrid->_processors[d]);
|
||||||
}
|
}
|
||||||
return new GridCartesian(latt5,simd5,mpi5,*FourDimGrid);
|
return new GridCartesian(latt5,simd5,mpi5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -68,14 +68,18 @@ GridRedBlackCartesian *SpaceTimeGrid::makeFiveDimRedBlackGrid(int Ls,const GridC
|
|||||||
{
|
{
|
||||||
int N4=FourDimGrid->_ndimension;
|
int N4=FourDimGrid->_ndimension;
|
||||||
int cbd=1;
|
int cbd=1;
|
||||||
|
std::vector<int> latt5(1,Ls);
|
||||||
|
std::vector<int> simd5(1,1);
|
||||||
|
std::vector<int> mpi5(1,1);
|
||||||
std::vector<int> cb5(1,0);
|
std::vector<int> cb5(1,0);
|
||||||
|
|
||||||
for(int d=0;d<N4;d++){
|
for(int d=0;d<N4;d++){
|
||||||
|
latt5.push_back(FourDimGrid->_fdimensions[d]);
|
||||||
|
simd5.push_back(FourDimGrid->_simd_layout[d]);
|
||||||
|
mpi5.push_back(FourDimGrid->_processors[d]);
|
||||||
cb5.push_back( 1);
|
cb5.push_back( 1);
|
||||||
}
|
}
|
||||||
GridCartesian *tmp = makeFiveDimGrid(Ls,FourDimGrid);
|
return new GridRedBlackCartesian(latt5,simd5,mpi5,cb5,cbd);
|
||||||
GridRedBlackCartesian *ret = new GridRedBlackCartesian(tmp,cb5,cbd);
|
|
||||||
delete tmp;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -93,24 +97,26 @@ GridCartesian *SpaceTimeGrid::makeFiveDimDWFGrid(int Ls,const GridCartes
|
|||||||
simd5.push_back(1);
|
simd5.push_back(1);
|
||||||
mpi5.push_back(FourDimGrid->_processors[d]);
|
mpi5.push_back(FourDimGrid->_processors[d]);
|
||||||
}
|
}
|
||||||
return new GridCartesian(latt5,simd5,mpi5,*FourDimGrid);
|
return new GridCartesian(latt5,simd5,mpi5);
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////
|
|
||||||
// Interface is inefficient and forces the deletion
|
|
||||||
// Pass in the non-redblack grid
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
GridRedBlackCartesian *SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(int Ls,const GridCartesian *FourDimGrid)
|
GridRedBlackCartesian *SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(int Ls,const GridCartesian *FourDimGrid)
|
||||||
{
|
{
|
||||||
int N4=FourDimGrid->_ndimension;
|
int N4=FourDimGrid->_ndimension;
|
||||||
|
int nsimd = FourDimGrid->Nsimd();
|
||||||
int cbd=1;
|
int cbd=1;
|
||||||
|
std::vector<int> latt5(1,Ls);
|
||||||
|
std::vector<int> simd5(1,nsimd);
|
||||||
|
std::vector<int> mpi5(1,1);
|
||||||
std::vector<int> cb5(1,0);
|
std::vector<int> cb5(1,0);
|
||||||
|
|
||||||
for(int d=0;d<N4;d++){
|
for(int d=0;d<N4;d++){
|
||||||
|
latt5.push_back(FourDimGrid->_fdimensions[d]);
|
||||||
|
simd5.push_back(1);
|
||||||
|
mpi5.push_back(FourDimGrid->_processors[d]);
|
||||||
cb5.push_back(1);
|
cb5.push_back(1);
|
||||||
}
|
}
|
||||||
GridCartesian *tmp = makeFiveDimDWFGrid(Ls,FourDimGrid);
|
return new GridRedBlackCartesian(latt5,simd5,mpi5,cb5,cbd);
|
||||||
GridRedBlackCartesian *ret = new GridRedBlackCartesian(tmp,cb5,cbd);
|
|
||||||
delete tmp;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace Grid {
|
|||||||
or element<T>::is_number;
|
or element<T>::is_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Vector flattening utility class ////////////////////////////////////////////
|
// Vector flatening utility class ////////////////////////////////////////////
|
||||||
// Class to flatten a multidimensional std::vector
|
// Class to flatten a multidimensional std::vector
|
||||||
template <typename V>
|
template <typename V>
|
||||||
class Flatten
|
class Flatten
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ JSONWriter::~JSONWriter(void)
|
|||||||
|
|
||||||
// write prettified JSON to file
|
// write prettified JSON to file
|
||||||
std::ofstream os(fileName_);
|
std::ofstream os(fileName_);
|
||||||
//std::cout << "JSONWriter::~JSONWriter" << std::endl;
|
|
||||||
os << std::setw(2) << json::parse(ss_.str()) << std::endl;
|
os << std::setw(2) << json::parse(ss_.str()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +56,6 @@ void JSONWriter::push(const string &s)
|
|||||||
|
|
||||||
void JSONWriter::pop(void)
|
void JSONWriter::pop(void)
|
||||||
{
|
{
|
||||||
//std::cout << "JSONWriter::pop" << std::endl;
|
|
||||||
delete_comma();
|
delete_comma();
|
||||||
ss_ << "},";
|
ss_ << "},";
|
||||||
}
|
}
|
||||||
@@ -69,22 +67,20 @@ void JSONWriter::delete_comma()
|
|||||||
ss_.str(dlast);
|
ss_.str(dlast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// here we are hitting a g++ bug (Bug 56480)
|
// here we are hitting a g++ bug (Bug 56480)
|
||||||
// compiles fine with clang
|
// compiles fine with clang
|
||||||
// have to wrap in the Grid namespace
|
// have to wrap in the Grid namespace
|
||||||
// annoying, but necessary for TravisCI
|
// annoying, but necessary for TravisCI
|
||||||
namespace Grid
|
namespace Grid
|
||||||
{
|
{
|
||||||
void JSONWriter::writeDefault(const std::string &s, const std::string &x)
|
template<>
|
||||||
|
void JSONWriter::writeDefault(const std::string &s,
|
||||||
|
const std::string &x)
|
||||||
{
|
{
|
||||||
//std::cout << "JSONWriter::writeDefault(string) : " << s << std::endl;
|
|
||||||
std::ostringstream os;
|
|
||||||
os << std::boolalpha << x;
|
|
||||||
if (s.size())
|
if (s.size())
|
||||||
ss_ << "\""<< s << "\" : \"" << os.str() << "\" ," ;
|
ss_ << "\""<< s << "\" : \"" << x << "\" ," ;
|
||||||
else
|
else
|
||||||
ss_ << os.str() << " ," ;
|
ss_ << "\"" << x << "\" ," ;
|
||||||
}
|
}
|
||||||
}// namespace Grid
|
}// namespace Grid
|
||||||
|
|
||||||
@@ -142,7 +138,6 @@ void JSONReader::pop(void)
|
|||||||
|
|
||||||
bool JSONReader::nextElement(const std::string &s)
|
bool JSONReader::nextElement(const std::string &s)
|
||||||
{
|
{
|
||||||
// Work in progress
|
|
||||||
// JSON dictionaries do not support multiple names
|
// JSON dictionaries do not support multiple names
|
||||||
// Same name objects must be packed in vectors
|
// Same name objects must be packed in vectors
|
||||||
++it_;
|
++it_;
|
||||||
|
|||||||
@@ -58,15 +58,10 @@ namespace Grid
|
|||||||
void writeDefault(const std::string &s, const std::complex<U> &x);
|
void writeDefault(const std::string &s, const std::complex<U> &x);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void writeDefault(const std::string &s, const std::vector<U> &x);
|
void writeDefault(const std::string &s, const std::vector<U> &x);
|
||||||
template <typename U, typename P>
|
|
||||||
void writeDefault(const std::string &s, const std::pair<U,P> &x);
|
|
||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
void writeDefault(const std::string &s, const char(&x)[N]);
|
void writeDefault(const std::string &s, const char(&x)[N]);
|
||||||
|
|
||||||
void writeDefault(const std::string &s, const std::string &x);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void delete_comma();
|
void delete_comma();
|
||||||
std::string fileName_;
|
std::string fileName_;
|
||||||
@@ -87,8 +82,6 @@ namespace Grid
|
|||||||
void readDefault(const std::string &s, std::complex<U> &output);
|
void readDefault(const std::string &s, std::complex<U> &output);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void readDefault(const std::string &s, std::vector<U> &output);
|
void readDefault(const std::string &s, std::vector<U> &output);
|
||||||
template <typename U, typename P>
|
|
||||||
void readDefault(const std::string &s, std::pair<U,P> &output);
|
|
||||||
private:
|
private:
|
||||||
json jobject_; // main object
|
json jobject_; // main object
|
||||||
json jcur_; // current json object
|
json jcur_; // current json object
|
||||||
@@ -113,7 +106,7 @@ namespace Grid
|
|||||||
template <typename U>
|
template <typename U>
|
||||||
void JSONWriter::writeDefault(const std::string &s, const U &x)
|
void JSONWriter::writeDefault(const std::string &s, const U &x)
|
||||||
{
|
{
|
||||||
//std::cout << "JSONWriter::writeDefault(U) : " << s << " " << x <<std::endl;
|
//std::cout << "JSONReader::writeDefault(U) : " << s << std::endl;
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << std::boolalpha << x;
|
os << std::boolalpha << x;
|
||||||
if (s.size())
|
if (s.size())
|
||||||
@@ -125,7 +118,7 @@ namespace Grid
|
|||||||
template <typename U>
|
template <typename U>
|
||||||
void JSONWriter::writeDefault(const std::string &s, const std::complex<U> &x)
|
void JSONWriter::writeDefault(const std::string &s, const std::complex<U> &x)
|
||||||
{
|
{
|
||||||
//std::cout << "JSONWriter::writeDefault(complex) : " << s << " " << x << std::endl;
|
//std::cout << "JSONReader::writeDefault(complex) : " << s << std::endl;
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "["<< std::boolalpha << x.real() << ", " << x.imag() << "]";
|
os << "["<< std::boolalpha << x.real() << ", " << x.imag() << "]";
|
||||||
if (s.size())
|
if (s.size())
|
||||||
@@ -134,22 +127,10 @@ namespace Grid
|
|||||||
ss_ << os.str() << " ," ;
|
ss_ << os.str() << " ," ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U, typename P>
|
|
||||||
void JSONWriter::writeDefault(const std::string &s, const std::pair<U,P> &x)
|
|
||||||
{
|
|
||||||
//std::cout << "JSONWriter::writeDefault(pair) : " << s << " " << x << std::endl;
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "["<< std::boolalpha << "\""<< x.first << "\" , \"" << x.second << "\" ]";
|
|
||||||
if (s.size())
|
|
||||||
ss_ << "\""<< s << "\" : " << os.str() << " ," ;
|
|
||||||
else
|
|
||||||
ss_ << os.str() << " ," ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void JSONWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
void JSONWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||||
{
|
{
|
||||||
//std::cout << "JSONWriter::writeDefault(vec U) : " << s << std::endl;
|
//std::cout << "JSONReader::writeDefault(vec U) : " << s << std::endl;
|
||||||
|
|
||||||
if (s.size())
|
if (s.size())
|
||||||
ss_ << " \""<<s<<"\" : [";
|
ss_ << " \""<<s<<"\" : [";
|
||||||
@@ -165,7 +146,7 @@ namespace Grid
|
|||||||
|
|
||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
void JSONWriter::writeDefault(const std::string &s, const char(&x)[N]){
|
void JSONWriter::writeDefault(const std::string &s, const char(&x)[N]){
|
||||||
//std::cout << "JSONWriter::writeDefault(char U) : " << s << " " << x << std::endl;
|
//std::cout << "JSONReader::writeDefault(char U) : " << s << std::endl;
|
||||||
|
|
||||||
if (s.size())
|
if (s.size())
|
||||||
ss_ << "\""<< s << "\" : \"" << x << "\" ," ;
|
ss_ << "\""<< s << "\" : \"" << x << "\" ," ;
|
||||||
@@ -192,30 +173,6 @@ namespace Grid
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reader template implementation ////////////////////////////////////////////
|
|
||||||
template <typename U, typename P>
|
|
||||||
void JSONReader::readDefault(const std::string &s, std::pair<U,P> &output)
|
|
||||||
{
|
|
||||||
U first;
|
|
||||||
P second;
|
|
||||||
json j;
|
|
||||||
if (s.size()){
|
|
||||||
//std::cout << "JSONReader::readDefault(pair) : " << s << " | "<< jcur_[s] << std::endl;
|
|
||||||
j = jcur_[s];
|
|
||||||
} else {
|
|
||||||
j = jcur_;
|
|
||||||
}
|
|
||||||
json::iterator it = j.begin();
|
|
||||||
jcur_ = *it;
|
|
||||||
read("", first);
|
|
||||||
it++;
|
|
||||||
jcur_ = *it;
|
|
||||||
read("", second);
|
|
||||||
output = std::pair<U,P>(first,second);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void JSONReader::readDefault(const std::string &s, std::complex<U> &output)
|
void JSONReader::readDefault(const std::string &s, std::complex<U> &output)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,11 +82,11 @@ namespace Optimization {
|
|||||||
double tmp[2]={a,b};
|
double tmp[2]={a,b};
|
||||||
return vld1q_f64(tmp);
|
return vld1q_f64(tmp);
|
||||||
}
|
}
|
||||||
//Real double
|
//Real double // N:tbc
|
||||||
inline float64x2_t operator()(double a){
|
inline float64x2_t operator()(double a){
|
||||||
return vdupq_n_f64(a);
|
return vdupq_n_f64(a);
|
||||||
}
|
}
|
||||||
//Integer
|
//Integer // N:tbc
|
||||||
inline uint32x4_t operator()(Integer a){
|
inline uint32x4_t operator()(Integer a){
|
||||||
return vdupq_n_u32(a);
|
return vdupq_n_u32(a);
|
||||||
}
|
}
|
||||||
@@ -124,32 +124,33 @@ namespace Optimization {
|
|||||||
// Nils: Vset untested; not used currently in Grid at all;
|
// Nils: Vset untested; not used currently in Grid at all;
|
||||||
// git commit 4a8c4ccfba1d05159348d21a9698028ea847e77b
|
// git commit 4a8c4ccfba1d05159348d21a9698028ea847e77b
|
||||||
struct Vset{
|
struct Vset{
|
||||||
// Complex float
|
// Complex float // N:ok
|
||||||
inline float32x4_t operator()(Grid::ComplexF *a){
|
inline float32x4_t operator()(Grid::ComplexF *a){
|
||||||
float tmp[4]={a[1].imag(),a[1].real(),a[0].imag(),a[0].real()};
|
float tmp[4]={a[1].imag(),a[1].real(),a[0].imag(),a[0].real()};
|
||||||
return vld1q_f32(tmp);
|
return vld1q_f32(tmp);
|
||||||
}
|
}
|
||||||
// Complex double
|
// Complex double // N:ok
|
||||||
inline float64x2_t operator()(Grid::ComplexD *a){
|
inline float64x2_t operator()(Grid::ComplexD *a){
|
||||||
double tmp[2]={a[0].imag(),a[0].real()};
|
double tmp[2]={a[0].imag(),a[0].real()};
|
||||||
return vld1q_f64(tmp);
|
return vld1q_f64(tmp);
|
||||||
}
|
}
|
||||||
// Real float
|
// Real float // N:ok
|
||||||
inline float32x4_t operator()(float *a){
|
inline float32x4_t operator()(float *a){
|
||||||
float tmp[4]={a[3],a[2],a[1],a[0]};
|
float tmp[4]={a[3],a[2],a[1],a[0]};
|
||||||
return vld1q_f32(tmp);
|
return vld1q_f32(tmp);
|
||||||
}
|
}
|
||||||
// Real double
|
// Real double // N:ok
|
||||||
inline float64x2_t operator()(double *a){
|
inline float64x2_t operator()(double *a){
|
||||||
double tmp[2]={a[1],a[0]};
|
double tmp[2]={a[1],a[0]};
|
||||||
return vld1q_f64(tmp);
|
return vld1q_f64(tmp);
|
||||||
}
|
}
|
||||||
// Integer
|
// Integer // N:ok
|
||||||
inline uint32x4_t operator()(Integer *a){
|
inline uint32x4_t operator()(Integer *a){
|
||||||
return vld1q_dup_u32(a);
|
return vld1q_dup_u32(a);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// N:leaving as is
|
||||||
template <typename Out_type, typename In_type>
|
template <typename Out_type, typename In_type>
|
||||||
struct Reduce{
|
struct Reduce{
|
||||||
//Need templated class to overload output type
|
//Need templated class to overload output type
|
||||||
@@ -420,6 +421,11 @@ namespace Optimization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// working, but no restriction on n
|
||||||
|
// template<int n> static inline float32x4_t tRotate(float32x4_t in){ return vextq_f32(in,in,n); };
|
||||||
|
// template<int n> static inline float64x2_t tRotate(float64x2_t in){ return vextq_f64(in,in,n); };
|
||||||
|
|
||||||
|
// restriction on n
|
||||||
template<int n> static inline float32x4_t tRotate(float32x4_t in){ return vextq_f32(in,in,n%4); };
|
template<int n> static inline float32x4_t tRotate(float32x4_t in){ return vextq_f32(in,in,n%4); };
|
||||||
template<int n> static inline float64x2_t tRotate(float64x2_t in){ return vextq_f64(in,in,n%2); };
|
template<int n> static inline float64x2_t tRotate(float64x2_t in){ return vextq_f64(in,in,n%2); };
|
||||||
|
|
||||||
@@ -541,7 +547,7 @@ namespace Optimization {
|
|||||||
|
|
||||||
|
|
||||||
//Complex double Reduce
|
//Complex double Reduce
|
||||||
template<>
|
template<> // N:by Boyle
|
||||||
inline Grid::ComplexD Reduce<Grid::ComplexD, float64x2_t>::operator()(float64x2_t in){
|
inline Grid::ComplexD Reduce<Grid::ComplexD, float64x2_t>::operator()(float64x2_t in){
|
||||||
u128d conv; conv.v = in;
|
u128d conv; conv.v = in;
|
||||||
return Grid::ComplexD(conv.f[0],conv.f[1]);
|
return Grid::ComplexD(conv.f[0],conv.f[1]);
|
||||||
@@ -556,7 +562,9 @@ namespace Optimization {
|
|||||||
//Integer Reduce
|
//Integer Reduce
|
||||||
template<>
|
template<>
|
||||||
inline Integer Reduce<Integer, uint32x4_t>::operator()(uint32x4_t in){
|
inline Integer Reduce<Integer, uint32x4_t>::operator()(uint32x4_t in){
|
||||||
return vaddvq_u32(in);
|
// FIXME unimplemented
|
||||||
|
printf("Reduce : Missing integer implementation -> FIX\n");
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,4 +604,3 @@ namespace Optimization {
|
|||||||
typedef Optimization::TimesI TimesISIMD;
|
typedef Optimization::TimesI TimesISIMD;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -376,18 +376,7 @@ class Grid_simd {
|
|||||||
Optimization::Exchange::Exchange0(out1.v,out2.v,in1.v,in2.v);
|
Optimization::Exchange::Exchange0(out1.v,out2.v,in1.v,in2.v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
friend inline void exchange0(Grid_simd &out1,Grid_simd &out2,Grid_simd in1,Grid_simd in2){
|
|
||||||
Optimization::Exchange::Exchange0(out1.v,out2.v,in1.v,in2.v);
|
|
||||||
}
|
|
||||||
friend inline void exchange1(Grid_simd &out1,Grid_simd &out2,Grid_simd in1,Grid_simd in2){
|
|
||||||
Optimization::Exchange::Exchange1(out1.v,out2.v,in1.v,in2.v);
|
|
||||||
}
|
|
||||||
friend inline void exchange2(Grid_simd &out1,Grid_simd &out2,Grid_simd in1,Grid_simd in2){
|
|
||||||
Optimization::Exchange::Exchange2(out1.v,out2.v,in1.v,in2.v);
|
|
||||||
}
|
|
||||||
friend inline void exchange3(Grid_simd &out1,Grid_simd &out2,Grid_simd in1,Grid_simd in2){
|
|
||||||
Optimization::Exchange::Exchange3(out1.v,out2.v,in1.v,in2.v);
|
|
||||||
}
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// General permute; assumes vector length is same across
|
// General permute; assumes vector length is same across
|
||||||
// all subtypes; may not be a good assumption, but could
|
// all subtypes; may not be a good assumption, but could
|
||||||
|
|||||||
@@ -400,13 +400,11 @@ class CartesianStencil { // Stencil runs along coordinate axes only; NO diagonal
|
|||||||
if ( sshift[0] == sshift[1] ) {
|
if ( sshift[0] == sshift[1] ) {
|
||||||
if (splice_dim) {
|
if (splice_dim) {
|
||||||
splicetime-=usecond();
|
splicetime-=usecond();
|
||||||
auto tmp = GatherSimd(source,dimension,shift,0x3,compress,face_idx);
|
same_node = same_node && GatherSimd(source,dimension,shift,0x3,compress,face_idx);
|
||||||
same_node = same_node && tmp;
|
|
||||||
splicetime+=usecond();
|
splicetime+=usecond();
|
||||||
} else {
|
} else {
|
||||||
nosplicetime-=usecond();
|
nosplicetime-=usecond();
|
||||||
auto tmp = Gather(source,dimension,shift,0x3,compress,face_idx);
|
same_node = same_node && Gather(source,dimension,shift,0x3,compress,face_idx);
|
||||||
same_node = same_node && tmp;
|
|
||||||
nosplicetime+=usecond();
|
nosplicetime+=usecond();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -414,15 +412,13 @@ class CartesianStencil { // Stencil runs along coordinate axes only; NO diagonal
|
|||||||
splicetime-=usecond();
|
splicetime-=usecond();
|
||||||
// if checkerboard is unfavourable take two passes
|
// if checkerboard is unfavourable take two passes
|
||||||
// both with block stride loop iteration
|
// both with block stride loop iteration
|
||||||
auto tmp1 = GatherSimd(source,dimension,shift,0x1,compress,face_idx);
|
same_node = same_node && GatherSimd(source,dimension,shift,0x1,compress,face_idx);
|
||||||
auto tmp2 = GatherSimd(source,dimension,shift,0x2,compress,face_idx);
|
same_node = same_node && GatherSimd(source,dimension,shift,0x2,compress,face_idx);
|
||||||
same_node = same_node && tmp1 && tmp2;
|
|
||||||
splicetime+=usecond();
|
splicetime+=usecond();
|
||||||
} else {
|
} else {
|
||||||
nosplicetime-=usecond();
|
nosplicetime-=usecond();
|
||||||
auto tmp1 = Gather(source,dimension,shift,0x1,compress,face_idx);
|
same_node = same_node && Gather(source,dimension,shift,0x1,compress,face_idx);
|
||||||
auto tmp2 = Gather(source,dimension,shift,0x2,compress,face_idx);
|
same_node = same_node && Gather(source,dimension,shift,0x2,compress,face_idx);
|
||||||
same_node = same_node && tmp1 && tmp2;
|
|
||||||
nosplicetime+=usecond();
|
nosplicetime+=usecond();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ class TensorIndexRecursion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<class vtype,int N> inline static
|
template<class vtype,int N> inline static
|
||||||
void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0],0,0)),N> &arg, int i,int j)
|
void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0],0)),N> &arg, int i,int j)
|
||||||
{
|
{
|
||||||
for(int ii=0;ii<N;ii++){
|
for(int ii=0;ii<N;ii++){
|
||||||
TensorIndexRecursion<Level-1>::pokeIndex(ret._internal[ii],arg._internal[ii],i,j);
|
TensorIndexRecursion<Level-1>::pokeIndex(ret._internal[ii],arg._internal[ii],i,j);
|
||||||
@@ -191,7 +191,7 @@ class TensorIndexRecursion {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
template<class vtype,int N> inline static
|
template<class vtype,int N> inline static
|
||||||
void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0][0],0,0)),N> &arg, int i,int j)
|
void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0][0],0)),N> &arg, int i,int j)
|
||||||
{
|
{
|
||||||
for(int ii=0;ii<N;ii++){
|
for(int ii=0;ii<N;ii++){
|
||||||
for(int jj=0;jj<N;jj++){
|
for(int jj=0;jj<N;jj++){
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Grid{
|
|||||||
class Lexicographic {
|
class Lexicographic {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static inline void CoorFromIndex (std::vector<int>& coor,int index,const std::vector<int> &dims){
|
static inline void CoorFromIndex (std::vector<int>& coor,int index,std::vector<int> &dims){
|
||||||
int nd= dims.size();
|
int nd= dims.size();
|
||||||
coor.resize(nd);
|
coor.resize(nd);
|
||||||
for(int d=0;d<nd;d++){
|
for(int d=0;d<nd;d++){
|
||||||
@@ -16,7 +16,7 @@ namespace Grid{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void IndexFromCoor (const std::vector<int>& coor,int &index,const std::vector<int> &dims){
|
static inline void IndexFromCoor (std::vector<int>& coor,int &index,std::vector<int> &dims){
|
||||||
int nd=dims.size();
|
int nd=dims.size();
|
||||||
int stride=1;
|
int stride=1;
|
||||||
index=0;
|
index=0;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
#include <Grid/Grid.h>
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace Grid;
|
using namespace Grid;
|
||||||
using namespace Grid::QCD;
|
using namespace Grid::QCD;
|
||||||
|
|
||||||
@@ -150,11 +151,6 @@ int main(int argc,char **argv)
|
|||||||
ioTest<TextWriter, TextReader>("iotest.dat", obj, "text (object) ");
|
ioTest<TextWriter, TextReader>("iotest.dat", obj, "text (object) ");
|
||||||
ioTest<TextWriter, TextReader>("iotest.dat", vec, "text (vector of objects)");
|
ioTest<TextWriter, TextReader>("iotest.dat", vec, "text (vector of objects)");
|
||||||
ioTest<TextWriter, TextReader>("iotest.dat", pair, "text (pair of objects)");
|
ioTest<TextWriter, TextReader>("iotest.dat", pair, "text (pair of objects)");
|
||||||
//// text
|
|
||||||
ioTest<JSONWriter, JSONReader>("iotest.json", obj, "JSON (object) ");
|
|
||||||
ioTest<JSONWriter, JSONReader>("iotest.json", vec, "JSON (vector of objects)");
|
|
||||||
ioTest<JSONWriter, JSONReader>("iotest.json", pair, "JSON (pair of objects)");
|
|
||||||
|
|
||||||
//// HDF5
|
//// HDF5
|
||||||
#undef HAVE_HDF5
|
#undef HAVE_HDF5
|
||||||
#ifdef HAVE_HDF5
|
#ifdef HAVE_HDF5
|
||||||
@@ -205,10 +201,8 @@ int main(int argc,char **argv)
|
|||||||
JSONWriter JW("bother.json");
|
JSONWriter JW("bother.json");
|
||||||
|
|
||||||
// test basic type writing
|
// test basic type writing
|
||||||
myenum a = myenum::red;
|
|
||||||
push(JW,"BasicTypes");
|
push(JW,"BasicTypes");
|
||||||
write(JW,std::string("i16"),i16);
|
write(JW,std::string("i16"),i16);
|
||||||
write(JW,"myenum",a);
|
|
||||||
write(JW,"u16",u16);
|
write(JW,"u16",u16);
|
||||||
write(JW,"i32",i32);
|
write(JW,"i32",i32);
|
||||||
write(JW,"u32",u32);
|
write(JW,"u32",u32);
|
||||||
@@ -219,14 +213,13 @@ int main(int argc,char **argv)
|
|||||||
write(JW,"b",b);
|
write(JW,"b",b);
|
||||||
pop(JW);
|
pop(JW);
|
||||||
|
|
||||||
|
|
||||||
// test serializable class writing
|
// test serializable class writing
|
||||||
myclass obj(1234); // non-trivial constructor
|
myclass obj(1234); // non-trivial constructor
|
||||||
std::cout << obj << std::endl;
|
|
||||||
std::cout << "-- serialisable class writing to 'bother.json'..." << std::endl;
|
std::cout << "-- serialisable class writing to 'bother.json'..." << std::endl;
|
||||||
write(JW,"obj",obj);
|
write(JW,"obj",obj);
|
||||||
JW.write("obj2", obj);
|
JW.write("obj2", obj);
|
||||||
|
|
||||||
|
std::cout << obj << std::endl;
|
||||||
|
|
||||||
std::vector<myclass> vec;
|
std::vector<myclass> vec;
|
||||||
vec.push_back(myclass(1234));
|
vec.push_back(myclass(1234));
|
||||||
@@ -236,7 +229,6 @@ int main(int argc,char **argv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
JSONReader RD("bother.json");
|
JSONReader RD("bother.json");
|
||||||
myclass jcopy1;
|
myclass jcopy1;
|
||||||
@@ -247,7 +239,6 @@ int main(int argc,char **argv)
|
|||||||
std::cout << jcopy1 << std::endl << jveccopy1 << std::endl;
|
std::cout << jcopy1 << std::endl << jveccopy1 << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// This is still work in progress
|
// This is still work in progress
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -80,47 +80,31 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
|
|
||||||
LatticeFermionD src_o(FrbGrid);
|
LatticeFermionD src_o(FrbGrid);
|
||||||
LatticeFermionD result_cg(FrbGrid);
|
LatticeFermionD result_o(FrbGrid);
|
||||||
|
LatticeFermionD result_o_2(FrbGrid);
|
||||||
pickCheckerboard(Odd,src_o,src);
|
pickCheckerboard(Odd,src_o,src);
|
||||||
result_cg.checkerboard = Odd;
|
result_o.checkerboard = Odd;
|
||||||
result_cg = zero;
|
result_o = zero;
|
||||||
LatticeFermionD result_mcg(result_cg);
|
result_o_2.checkerboard = Odd;
|
||||||
LatticeFermionD result_rlcg(result_cg);
|
result_o_2 = zero;
|
||||||
|
|
||||||
SchurDiagMooeeOperator<DomainWallFermionD,LatticeFermionD> HermOpEO(Ddwf);
|
SchurDiagMooeeOperator<DomainWallFermionD,LatticeFermionD> HermOpEO(Ddwf);
|
||||||
SchurDiagMooeeOperator<DomainWallFermionFH,LatticeFermionF> HermOpEO_f(Ddwf_f);
|
SchurDiagMooeeOperator<DomainWallFermionFH,LatticeFermionF> HermOpEO_f(Ddwf_f);
|
||||||
|
|
||||||
//#define DO_MIXED_CG
|
|
||||||
#define DO_RLUP_CG
|
|
||||||
|
|
||||||
#ifdef DO_MIXED_CG
|
|
||||||
std::cout << "Starting mixed CG" << std::endl;
|
std::cout << "Starting mixed CG" << std::endl;
|
||||||
MixedPrecisionConjugateGradient<LatticeFermionD,LatticeFermionF> mCG(1.0e-8, 10000, 50, FrbGrid_f, HermOpEO_f, HermOpEO);
|
MixedPrecisionConjugateGradient<LatticeFermionD,LatticeFermionF> mCG(1.0e-8, 10000, 50, FrbGrid_f, HermOpEO_f, HermOpEO);
|
||||||
mCG.InnerTolerance = 3.0e-5;
|
mCG.InnerTolerance = 3.0e-5;
|
||||||
mCG(src_o,result_mcg);
|
mCG(src_o,result_o);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DO_RLUP_CG
|
|
||||||
std::cout << "Starting reliable update CG" << std::endl;
|
|
||||||
ConjugateGradientReliableUpdate<LatticeFermionD,LatticeFermionF> rlCG(1.e-8, 10000, 0.1, FrbGrid_f, HermOpEO_f, HermOpEO);
|
|
||||||
rlCG(src_o,result_rlcg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::cout << "Starting regular CG" << std::endl;
|
std::cout << "Starting regular CG" << std::endl;
|
||||||
ConjugateGradient<LatticeFermionD> CG(1.0e-8,10000);
|
ConjugateGradient<LatticeFermionD> CG(1.0e-8,10000);
|
||||||
CG(HermOpEO,src_o,result_cg);
|
CG(HermOpEO,src_o,result_o_2);
|
||||||
|
|
||||||
#ifdef DO_MIXED_CG
|
LatticeFermionD diff_o(FrbGrid);
|
||||||
LatticeFermionD diff_mcg(FrbGrid);
|
RealD diff = axpy_norm(diff_o, -1.0, result_o, result_o_2);
|
||||||
RealD vdiff_mcg = axpy_norm(diff_mcg, -1.0, result_cg, result_mcg);
|
|
||||||
std::cout << "Diff between mixed and regular CG: " << vdiff_mcg << std::endl;
|
std::cout << "Diff between mixed and regular CG: " << diff << std::endl;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DO_RLUP_CG
|
|
||||||
LatticeFermionD diff_rlcg(FrbGrid);
|
|
||||||
RealD vdiff_rlcg = axpy_norm(diff_rlcg, -1.0, result_cg, result_rlcg);
|
|
||||||
std::cout << "Diff between reliable update and regular CG: " << vdiff_rlcg << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Grid_finalize();
|
Grid_finalize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ int main(int argc, char ** argv) {
|
|||||||
double volume = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
double volume = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
|
|
||||||
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
|
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian rbFine(&Fine);
|
GridRedBlackCartesian rbFine(latt_size,simd_layout,mpi_layout);
|
||||||
GridParallelRNG fRNG(&Fine);
|
GridParallelRNG fRNG(&Fine);
|
||||||
|
|
||||||
// fRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
|
// fRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ int main (int argc, char ** argv)
|
|||||||
mask[0]=0;
|
mask[0]=0;
|
||||||
|
|
||||||
GridCartesian Fine (latt_size,simd_layout,mpi_layout);
|
GridCartesian Fine (latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBFine(&Fine,mask,1);
|
GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout,mask,1);
|
||||||
|
|
||||||
GridParallelRNG FineRNG(&Fine); FineRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
GridParallelRNG FineRNG(&Fine); FineRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ int main (int argc, char ** argv)
|
|||||||
mask[0]=0;
|
mask[0]=0;
|
||||||
|
|
||||||
GridCartesian Fine (latt_size,simd_layout,mpi_layout);
|
GridCartesian Fine (latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBFine(&Fine,mask,1);
|
GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout,mask,1);
|
||||||
|
|
||||||
GridParallelRNG FineRNG(&Fine); FineRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
GridParallelRNG FineRNG(&Fine); FineRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
||||||
|
|
||||||
|
|||||||
@@ -1,239 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/core/Test_dwf_eofa_even_odd.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
template<class d>
|
|
||||||
struct scal {
|
|
||||||
d internal;
|
|
||||||
};
|
|
||||||
|
|
||||||
Gamma::Algebra Gmu [] = {
|
|
||||||
Gamma::Algebra::GammaX,
|
|
||||||
Gamma::Algebra::GammaY,
|
|
||||||
Gamma::Algebra::GammaZ,
|
|
||||||
Gamma::Algebra::GammaT
|
|
||||||
};
|
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
const int Ls = 8;
|
|
||||||
// GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
std::vector<int> seeds4({1,2,3,4});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
|
|
||||||
LatticeFermion src (FGrid); random(RNG5, src);
|
|
||||||
LatticeFermion phi (FGrid); random(RNG5, phi);
|
|
||||||
LatticeFermion chi (FGrid); random(RNG5, chi);
|
|
||||||
LatticeFermion result(FGrid); result = zero;
|
|
||||||
LatticeFermion ref (FGrid); ref = zero;
|
|
||||||
LatticeFermion tmp (FGrid); tmp = zero;
|
|
||||||
LatticeFermion err (FGrid); err = zero;
|
|
||||||
LatticeGaugeField Umu (UGrid); SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
std::vector<LatticeColourMatrix> U(4,UGrid);
|
|
||||||
|
|
||||||
// Only one non-zero (y)
|
|
||||||
Umu = zero;
|
|
||||||
for(int nn=0; nn<Nd; nn++){
|
|
||||||
random(RNG4, U[nn]);
|
|
||||||
if(nn>0){ U[nn] = zero; }
|
|
||||||
PokeIndex<LorentzIndex>(Umu, U[nn], nn);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD mq1 = 0.1;
|
|
||||||
RealD mq2 = 0.5;
|
|
||||||
RealD mq3 = 1.0;
|
|
||||||
RealD shift = 0.1234;
|
|
||||||
RealD M5 = 1.8;
|
|
||||||
int pm = 1;
|
|
||||||
DomainWallEOFAFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mq1, mq2, mq3, shift, pm, M5);
|
|
||||||
|
|
||||||
LatticeFermion src_e (FrbGrid);
|
|
||||||
LatticeFermion src_o (FrbGrid);
|
|
||||||
LatticeFermion r_e (FrbGrid);
|
|
||||||
LatticeFermion r_o (FrbGrid);
|
|
||||||
LatticeFermion r_eo (FGrid);
|
|
||||||
LatticeFermion r_eeoo(FGrid);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Testing that Meo + Moe + Moo + Mee = Munprec " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
|
||||||
|
|
||||||
pickCheckerboard(Even, src_e, src);
|
|
||||||
pickCheckerboard(Odd, src_o, src);
|
|
||||||
|
|
||||||
Ddwf.Meooe(src_e, r_o); std::cout << GridLogMessage << "Applied Meo" << std::endl;
|
|
||||||
Ddwf.Meooe(src_o, r_e); std::cout << GridLogMessage << "Applied Moe" << std::endl;
|
|
||||||
setCheckerboard(r_eo, r_o);
|
|
||||||
setCheckerboard(r_eo, r_e);
|
|
||||||
|
|
||||||
Ddwf.Mooee(src_e, r_e); std::cout << GridLogMessage << "Applied Mee" << std::endl;
|
|
||||||
Ddwf.Mooee(src_o, r_o); std::cout << GridLogMessage << "Applied Moo" << std::endl;
|
|
||||||
setCheckerboard(r_eeoo, r_e);
|
|
||||||
setCheckerboard(r_eeoo, r_o);
|
|
||||||
|
|
||||||
r_eo = r_eo + r_eeoo;
|
|
||||||
Ddwf.M(src, ref);
|
|
||||||
|
|
||||||
// std::cout << GridLogMessage << r_eo << std::endl;
|
|
||||||
// std::cout << GridLogMessage << ref << std::endl;
|
|
||||||
|
|
||||||
err = ref - r_eo;
|
|
||||||
std::cout << GridLogMessage << "EO norm diff " << norm2(err) << " " << norm2(ref) << " " << norm2(r_eo) << std::endl;
|
|
||||||
|
|
||||||
LatticeComplex cerr(FGrid);
|
|
||||||
cerr = localInnerProduct(err,err);
|
|
||||||
// std::cout << GridLogMessage << cerr << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test Ddagger is the dagger of D by requiring " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= < phi | Deo | chi > * = < chi | Deo^dag| phi> " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
LatticeFermion chi_e (FrbGrid);
|
|
||||||
LatticeFermion chi_o (FrbGrid);
|
|
||||||
|
|
||||||
LatticeFermion dchi_e(FrbGrid);
|
|
||||||
LatticeFermion dchi_o(FrbGrid);
|
|
||||||
|
|
||||||
LatticeFermion phi_e (FrbGrid);
|
|
||||||
LatticeFermion phi_o (FrbGrid);
|
|
||||||
|
|
||||||
LatticeFermion dphi_e(FrbGrid);
|
|
||||||
LatticeFermion dphi_o(FrbGrid);
|
|
||||||
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
pickCheckerboard(Even, phi_e, phi);
|
|
||||||
pickCheckerboard(Odd , phi_o, phi);
|
|
||||||
|
|
||||||
Ddwf.Meooe (chi_e, dchi_o);
|
|
||||||
Ddwf.Meooe (chi_o, dchi_e);
|
|
||||||
Ddwf.MeooeDag(phi_e, dphi_o);
|
|
||||||
Ddwf.MeooeDag(phi_o, dphi_e);
|
|
||||||
|
|
||||||
ComplexD pDce = innerProduct(phi_e, dchi_e);
|
|
||||||
ComplexD pDco = innerProduct(phi_o, dchi_o);
|
|
||||||
ComplexD cDpe = innerProduct(chi_e, dphi_e);
|
|
||||||
ComplexD cDpo = innerProduct(chi_o, dphi_o);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
|
||||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDce-conj(cDpo) << std::endl;
|
|
||||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDco-conj(cDpe) << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test MeeInv Mee = 1 " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
|
|
||||||
Ddwf.Mooee (chi_e, src_e);
|
|
||||||
Ddwf.MooeeInv(src_e, phi_e);
|
|
||||||
|
|
||||||
Ddwf.Mooee (chi_o, src_o);
|
|
||||||
Ddwf.MooeeInv(src_o, phi_o);
|
|
||||||
|
|
||||||
setCheckerboard(phi, phi_e);
|
|
||||||
setCheckerboard(phi, phi_o);
|
|
||||||
|
|
||||||
err = phi - chi;
|
|
||||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test MeeInvDag MeeDag = 1 " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
|
|
||||||
Ddwf.MooeeDag (chi_e, src_e);
|
|
||||||
Ddwf.MooeeInvDag(src_e, phi_e);
|
|
||||||
|
|
||||||
Ddwf.MooeeDag (chi_o, src_o);
|
|
||||||
Ddwf.MooeeInvDag(src_o, phi_o);
|
|
||||||
|
|
||||||
setCheckerboard(phi, phi_e);
|
|
||||||
setCheckerboard(phi, phi_o);
|
|
||||||
|
|
||||||
err = phi - chi;
|
|
||||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test MpcDagMpc is Hermitian " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
random(RNG5, phi);
|
|
||||||
random(RNG5, chi);
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
pickCheckerboard(Even, phi_e, phi);
|
|
||||||
pickCheckerboard(Odd , phi_o, phi);
|
|
||||||
RealD t1,t2;
|
|
||||||
|
|
||||||
SchurDiagMooeeOperator<DomainWallEOFAFermionR,LatticeFermion> HermOpEO(Ddwf);
|
|
||||||
HermOpEO.MpcDagMpc(chi_e, dchi_e, t1, t2);
|
|
||||||
HermOpEO.MpcDagMpc(chi_o, dchi_o, t1, t2);
|
|
||||||
|
|
||||||
HermOpEO.MpcDagMpc(phi_e, dphi_e, t1, t2);
|
|
||||||
HermOpEO.MpcDagMpc(phi_o, dphi_o, t1, t2);
|
|
||||||
|
|
||||||
pDce = innerProduct(phi_e, dchi_e);
|
|
||||||
pDco = innerProduct(phi_o, dchi_o);
|
|
||||||
cDpe = innerProduct(chi_e, dphi_e);
|
|
||||||
cDpo = innerProduct(chi_o, dphi_o);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
|
||||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDco-conj(cDpo) << std::endl;
|
|
||||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDce-conj(cDpe) << std::endl;
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ int main (int argc, char ** argv)
|
|||||||
vol = vol * latt_size[d];
|
vol = vol * latt_size[d];
|
||||||
}
|
}
|
||||||
GridCartesian GRID(latt_size,simd_layout,mpi_layout);
|
GridCartesian GRID(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGRID(&GRID);
|
GridRedBlackCartesian RBGRID(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
LatticeComplexD one(&GRID);
|
LatticeComplexD one(&GRID);
|
||||||
LatticeComplexD zz(&GRID);
|
LatticeComplexD zz(&GRID);
|
||||||
|
|||||||
@@ -33,68 +33,22 @@ using namespace std;
|
|||||||
using namespace Grid;
|
using namespace Grid;
|
||||||
using namespace Grid::QCD;
|
using namespace Grid::QCD;
|
||||||
|
|
||||||
//typedef GparityDomainWallFermionD GparityDiracOp;
|
typedef typename GparityDomainWallFermionR::FermionField FermionField;
|
||||||
//typedef DomainWallFermionD StandardDiracOp;
|
|
||||||
//#define DOP_PARAMS
|
|
||||||
|
|
||||||
typedef GparityMobiusFermionD GparityDiracOp;
|
|
||||||
typedef MobiusFermionD StandardDiracOp;
|
|
||||||
#define DOP_PARAMS ,1.5, 0.5
|
|
||||||
|
|
||||||
|
|
||||||
typedef typename GparityDiracOp::FermionField GparityFermionField;
|
|
||||||
typedef typename GparityDiracOp::GaugeField GparityGaugeField;
|
|
||||||
typedef typename GparityFermionField::vector_type vComplexType;
|
|
||||||
|
|
||||||
typedef typename StandardDiracOp::FermionField StandardFermionField;
|
|
||||||
typedef typename StandardDiracOp::GaugeField StandardGaugeField;
|
|
||||||
|
|
||||||
enum{ same_vComplex = std::is_same<vComplexType, typename StandardFermionField::vector_type>::value };
|
|
||||||
static_assert(same_vComplex == 1, "Dirac Operators must have same underlying SIMD complex type");
|
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
int main (int argc, char ** argv)
|
||||||
{
|
{
|
||||||
int nu = 0;
|
const int nu = 3;
|
||||||
|
|
||||||
Grid_init(&argc,&argv);
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
for(int i=1;i<argc;i++){
|
|
||||||
if(std::string(argv[i]) == "--Gparity-dir"){
|
|
||||||
std::stringstream ss; ss << argv[i+1]; ss >> nu;
|
|
||||||
std::cout << GridLogMessage << "Set Gparity direction to " << nu << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "* Testing Gparity Dirac operator "<<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplexType::Nsimd()<<std::endl;
|
|
||||||
#ifdef GRID_OMP
|
|
||||||
if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
|
|
||||||
if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
|
|
||||||
#endif
|
|
||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
|
|
||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using UNROLLED Nc=3 WilsonKernels" <<std::endl;
|
|
||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3 WilsonKernels" <<std::endl;
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
|
||||||
|
|
||||||
const int Ls=4;
|
const int Ls=4;
|
||||||
//const int L =4;
|
const int L =4;
|
||||||
//std::vector<int> latt_2f(Nd,L);
|
std::vector<int> latt_2f(Nd,L);
|
||||||
|
std::vector<int> latt_1f(Nd,L); latt_1f[nu] = 2*L;
|
||||||
std::vector<int> latt_2f = GridDefaultLatt();
|
|
||||||
std::vector<int> latt_1f(latt_2f); latt_1f[nu] = 2*latt_2f[nu];
|
|
||||||
int L = latt_2f[nu];
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplexType::Nsimd());
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "SIMD layout: ";
|
|
||||||
for(int i=0;i<simd_layout.size();i++) std::cout << simd_layout[i] << " ";
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi(); //node layout
|
std::vector<int> mpi_layout = GridDefaultMpi(); //node layout
|
||||||
|
|
||||||
GridCartesian * UGrid_1f = SpaceTimeGrid::makeFourDimGrid(latt_1f, simd_layout, mpi_layout);
|
GridCartesian * UGrid_1f = SpaceTimeGrid::makeFourDimGrid(latt_1f, simd_layout, mpi_layout);
|
||||||
@@ -113,13 +67,13 @@ int main (int argc, char ** argv)
|
|||||||
GridParallelRNG RNG5_2f(FGrid_2f); RNG5_2f.SeedFixedIntegers(seeds5);
|
GridParallelRNG RNG5_2f(FGrid_2f); RNG5_2f.SeedFixedIntegers(seeds5);
|
||||||
GridParallelRNG RNG4_2f(UGrid_2f); RNG4_2f.SeedFixedIntegers(seeds4);
|
GridParallelRNG RNG4_2f(UGrid_2f); RNG4_2f.SeedFixedIntegers(seeds4);
|
||||||
|
|
||||||
GparityGaugeField Umu_2f(UGrid_2f);
|
LatticeGaugeField Umu_2f(UGrid_2f);
|
||||||
SU3::HotConfiguration(RNG4_2f,Umu_2f);
|
SU3::HotConfiguration(RNG4_2f,Umu_2f);
|
||||||
|
|
||||||
StandardFermionField src (FGrid_2f);
|
LatticeFermion src (FGrid_2f);
|
||||||
StandardFermionField tmpsrc(FGrid_2f);
|
LatticeFermion tmpsrc(FGrid_2f);
|
||||||
GparityFermionField src_2f(FGrid_2f);
|
FermionField src_2f(FGrid_2f);
|
||||||
StandardFermionField src_1f(FGrid_1f);
|
LatticeFermion src_1f(FGrid_1f);
|
||||||
|
|
||||||
// Replicate fermion source
|
// Replicate fermion source
|
||||||
random(RNG5_2f,src);
|
random(RNG5_2f,src);
|
||||||
@@ -127,8 +81,8 @@ int main (int argc, char ** argv)
|
|||||||
tmpsrc=src*2.0;
|
tmpsrc=src*2.0;
|
||||||
PokeIndex<0>(src_2f,tmpsrc,1);
|
PokeIndex<0>(src_2f,tmpsrc,1);
|
||||||
|
|
||||||
StandardFermionField result_1f(FGrid_1f); result_1f=zero;
|
LatticeFermion result_1f(FGrid_1f); result_1f=zero;
|
||||||
StandardGaugeField Umu_1f(UGrid_1f);
|
LatticeGaugeField Umu_1f(UGrid_1f);
|
||||||
Replicate(Umu_2f,Umu_1f);
|
Replicate(Umu_2f,Umu_1f);
|
||||||
|
|
||||||
//Coordinate grid for reference
|
//Coordinate grid for reference
|
||||||
@@ -138,7 +92,7 @@ int main (int argc, char ** argv)
|
|||||||
//Copy-conjugate the gauge field
|
//Copy-conjugate the gauge field
|
||||||
//First C-shift the lattice by Lx/2
|
//First C-shift the lattice by Lx/2
|
||||||
{
|
{
|
||||||
StandardGaugeField Umu_shift = conjugate( Cshift(Umu_1f,nu,L) );
|
LatticeGaugeField Umu_shift = conjugate( Cshift(Umu_1f,nu,L) );
|
||||||
Umu_1f = where( xcoor_1f >= Integer(L), Umu_shift, Umu_1f );
|
Umu_1f = where( xcoor_1f >= Integer(L), Umu_shift, Umu_1f );
|
||||||
|
|
||||||
// hack test to check the same
|
// hack test to check the same
|
||||||
@@ -147,7 +101,7 @@ int main (int argc, char ** argv)
|
|||||||
cout << GridLogMessage << "Umu diff " << norm2(Umu_shift)<<std::endl;
|
cout << GridLogMessage << "Umu diff " << norm2(Umu_shift)<<std::endl;
|
||||||
|
|
||||||
//Make the gauge field antiperiodic in nu-direction
|
//Make the gauge field antiperiodic in nu-direction
|
||||||
decltype(PeekIndex<LorentzIndex>(Umu_1f,nu)) Unu(UGrid_1f);
|
LatticeColourMatrix Unu(UGrid_1f);
|
||||||
Unu = PeekIndex<LorentzIndex>(Umu_1f,nu);
|
Unu = PeekIndex<LorentzIndex>(Umu_1f,nu);
|
||||||
Unu = where(xcoor_1f == Integer(2*L-1), -Unu, Unu);
|
Unu = where(xcoor_1f == Integer(2*L-1), -Unu, Unu);
|
||||||
PokeIndex<LorentzIndex>(Umu_1f,Unu,nu);
|
PokeIndex<LorentzIndex>(Umu_1f,Unu,nu);
|
||||||
@@ -161,33 +115,33 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
RealD mass=0.0;
|
RealD mass=0.0;
|
||||||
RealD M5=1.8;
|
RealD M5=1.8;
|
||||||
StandardDiracOp Ddwf(Umu_1f,*FGrid_1f,*FrbGrid_1f,*UGrid_1f,*UrbGrid_1f,mass,M5 DOP_PARAMS);
|
DomainWallFermionR Ddwf(Umu_1f,*FGrid_1f,*FrbGrid_1f,*UGrid_1f,*UrbGrid_1f,mass,M5);
|
||||||
|
|
||||||
StandardFermionField src_o_1f(FrbGrid_1f);
|
LatticeFermion src_o_1f(FrbGrid_1f);
|
||||||
StandardFermionField result_o_1f(FrbGrid_1f);
|
LatticeFermion result_o_1f(FrbGrid_1f);
|
||||||
pickCheckerboard(Odd,src_o_1f,src_1f);
|
pickCheckerboard(Odd,src_o_1f,src_1f);
|
||||||
result_o_1f=zero;
|
result_o_1f=zero;
|
||||||
|
|
||||||
SchurDiagMooeeOperator<StandardDiracOp,StandardFermionField> HermOpEO(Ddwf);
|
SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
|
||||||
ConjugateGradient<StandardFermionField> CG(1.0e-8,10000);
|
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||||
CG(HermOpEO,src_o_1f,result_o_1f);
|
CG(HermOpEO,src_o_1f,result_o_1f);
|
||||||
|
|
||||||
// const int nu = 3;
|
// const int nu = 3;
|
||||||
std::vector<int> twists(Nd,0);
|
std::vector<int> twists(Nd,0);
|
||||||
twists[nu] = 1;
|
twists[nu] = 1;
|
||||||
GparityDiracOp::ImplParams params;
|
GparityDomainWallFermionR::ImplParams params;
|
||||||
params.twists = twists;
|
params.twists = twists;
|
||||||
GparityDiracOp GPDdwf(Umu_2f,*FGrid_2f,*FrbGrid_2f,*UGrid_2f,*UrbGrid_2f,mass,M5 DOP_PARAMS,params);
|
GparityDomainWallFermionR GPDdwf(Umu_2f,*FGrid_2f,*FrbGrid_2f,*UGrid_2f,*UrbGrid_2f,mass,M5,params);
|
||||||
|
|
||||||
for(int disp=-1;disp<=1;disp+=2)
|
for(int disp=-1;disp<=1;disp+=2)
|
||||||
for(int mu=0;mu<5;mu++)
|
for(int mu=0;mu<5;mu++)
|
||||||
{
|
{
|
||||||
GparityFermionField Dsrc_2f(FGrid_2f);
|
FermionField Dsrc_2f(FGrid_2f);
|
||||||
|
|
||||||
StandardFermionField Dsrc_1f(FGrid_1f);
|
LatticeFermion Dsrc_1f(FGrid_1f);
|
||||||
StandardFermionField Dsrc_2freplica(FGrid_1f);
|
LatticeFermion Dsrc_2freplica(FGrid_1f);
|
||||||
StandardFermionField Dsrc_2freplica0(FGrid_1f);
|
LatticeFermion Dsrc_2freplica0(FGrid_1f);
|
||||||
StandardFermionField Dsrc_2freplica1(FGrid_1f);
|
LatticeFermion Dsrc_2freplica1(FGrid_1f);
|
||||||
|
|
||||||
if ( mu ==0 ) {
|
if ( mu ==0 ) {
|
||||||
std::cout << GridLogMessage<< " Cross checking entire hopping term"<<std::endl;
|
std::cout << GridLogMessage<< " Cross checking entire hopping term"<<std::endl;
|
||||||
@@ -202,8 +156,8 @@ int main (int argc, char ** argv)
|
|||||||
std::cout << GridLogMessage << "S norms "<< norm2(src_2f) << " " << norm2(src_1f) <<std::endl;
|
std::cout << GridLogMessage << "S norms "<< norm2(src_2f) << " " << norm2(src_1f) <<std::endl;
|
||||||
std::cout << GridLogMessage << "D norms "<< norm2(Dsrc_2f)<< " " << norm2(Dsrc_1f) <<std::endl;
|
std::cout << GridLogMessage << "D norms "<< norm2(Dsrc_2f)<< " " << norm2(Dsrc_1f) <<std::endl;
|
||||||
|
|
||||||
StandardFermionField Dsrc_2f0(FGrid_2f); Dsrc_2f0 = PeekIndex<0>(Dsrc_2f,0);
|
LatticeFermion Dsrc_2f0(FGrid_2f); Dsrc_2f0 = PeekIndex<0>(Dsrc_2f,0);
|
||||||
StandardFermionField Dsrc_2f1(FGrid_2f); Dsrc_2f1 = PeekIndex<0>(Dsrc_2f,1);
|
LatticeFermion Dsrc_2f1(FGrid_2f); Dsrc_2f1 = PeekIndex<0>(Dsrc_2f,1);
|
||||||
|
|
||||||
// Dsrc_2f1 = Dsrc_2f1 - Dsrc_2f0;
|
// Dsrc_2f1 = Dsrc_2f1 - Dsrc_2f0;
|
||||||
// std::cout << GridLogMessage << " Cross check two halves " <<norm2(Dsrc_2f1)<<std::endl;
|
// std::cout << GridLogMessage << " Cross check two halves " <<norm2(Dsrc_2f1)<<std::endl;
|
||||||
@@ -220,20 +174,20 @@ int main (int argc, char ** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
GparityFermionField chi (FGrid_2f); gaussian(RNG5_2f,chi);
|
FermionField chi (FGrid_2f); gaussian(RNG5_2f,chi);
|
||||||
GparityFermionField phi (FGrid_2f); gaussian(RNG5_2f,phi);
|
FermionField phi (FGrid_2f); gaussian(RNG5_2f,phi);
|
||||||
|
|
||||||
GparityFermionField chi_e (FrbGrid_2f);
|
FermionField chi_e (FrbGrid_2f);
|
||||||
GparityFermionField chi_o (FrbGrid_2f);
|
FermionField chi_o (FrbGrid_2f);
|
||||||
|
|
||||||
GparityFermionField dchi_e (FrbGrid_2f);
|
FermionField dchi_e (FrbGrid_2f);
|
||||||
GparityFermionField dchi_o (FrbGrid_2f);
|
FermionField dchi_o (FrbGrid_2f);
|
||||||
|
|
||||||
GparityFermionField phi_e (FrbGrid_2f);
|
FermionField phi_e (FrbGrid_2f);
|
||||||
GparityFermionField phi_o (FrbGrid_2f);
|
FermionField phi_o (FrbGrid_2f);
|
||||||
|
|
||||||
GparityFermionField dphi_e (FrbGrid_2f);
|
FermionField dphi_e (FrbGrid_2f);
|
||||||
GparityFermionField dphi_o (FrbGrid_2f);
|
FermionField dphi_o (FrbGrid_2f);
|
||||||
|
|
||||||
pickCheckerboard(Even,chi_e,chi);
|
pickCheckerboard(Even,chi_e,chi);
|
||||||
pickCheckerboard(Odd ,chi_o,chi);
|
pickCheckerboard(Odd ,chi_o,chi);
|
||||||
@@ -258,14 +212,14 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GparityFermionField result_2f(FGrid_2f); result_2f=zero;
|
FermionField result_2f(FGrid_2f); result_2f=zero;
|
||||||
GparityFermionField src_o_2f(FrbGrid_2f);
|
FermionField src_o_2f(FrbGrid_2f);
|
||||||
GparityFermionField result_o_2f(FrbGrid_2f);
|
FermionField result_o_2f(FrbGrid_2f);
|
||||||
pickCheckerboard(Odd,src_o_2f,src_2f);
|
pickCheckerboard(Odd,src_o_2f,src_2f);
|
||||||
result_o_2f=zero;
|
result_o_2f=zero;
|
||||||
|
|
||||||
ConjugateGradient<GparityFermionField> CG2f(1.0e-8,10000);
|
ConjugateGradient<FermionField> CG2f(1.0e-8,10000);
|
||||||
SchurDiagMooeeOperator<GparityDiracOp,GparityFermionField> HermOpEO2f(GPDdwf);
|
SchurDiagMooeeOperator<GparityDomainWallFermionR,FermionField> HermOpEO2f(GPDdwf);
|
||||||
CG2f(HermOpEO2f,src_o_2f,result_o_2f);
|
CG2f(HermOpEO2f,src_o_2f,result_o_2f);
|
||||||
|
|
||||||
std::cout << "2f cb "<<result_o_2f.checkerboard<<std::endl;
|
std::cout << "2f cb "<<result_o_2f.checkerboard<<std::endl;
|
||||||
@@ -273,10 +227,10 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
std::cout << " result norms " <<norm2(result_o_2f)<<" " <<norm2(result_o_1f)<<std::endl;
|
std::cout << " result norms " <<norm2(result_o_2f)<<" " <<norm2(result_o_1f)<<std::endl;
|
||||||
|
|
||||||
StandardFermionField res0o (FrbGrid_2f);
|
LatticeFermion res0o (FrbGrid_2f);
|
||||||
StandardFermionField res1o (FrbGrid_2f);
|
LatticeFermion res1o (FrbGrid_2f);
|
||||||
StandardFermionField res0 (FGrid_2f);
|
LatticeFermion res0 (FGrid_2f);
|
||||||
StandardFermionField res1 (FGrid_2f);
|
LatticeFermion res1 (FGrid_2f);
|
||||||
|
|
||||||
res0=zero;
|
res0=zero;
|
||||||
res1=zero;
|
res1=zero;
|
||||||
@@ -290,9 +244,9 @@ int main (int argc, char ** argv)
|
|||||||
setCheckerboard(res0,res0o);
|
setCheckerboard(res0,res0o);
|
||||||
setCheckerboard(res1,res1o);
|
setCheckerboard(res1,res1o);
|
||||||
|
|
||||||
StandardFermionField replica (FGrid_1f);
|
LatticeFermion replica (FGrid_1f);
|
||||||
StandardFermionField replica0(FGrid_1f);
|
LatticeFermion replica0(FGrid_1f);
|
||||||
StandardFermionField replica1(FGrid_1f);
|
LatticeFermion replica1(FGrid_1f);
|
||||||
Replicate(res0,replica0);
|
Replicate(res0,replica0);
|
||||||
Replicate(res1,replica1);
|
Replicate(res1,replica1);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/Test_laplacian.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Guido Cossu <guido.cossu@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 */
|
|
||||||
#include <Grid/Grid.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc,&argv);
|
|
||||||
|
|
||||||
std::vector<int> latt_size = GridDefaultLatt();
|
|
||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
|
||||||
std::vector<int> 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;
|
|
||||||
|
|
||||||
GridParallelRNG pRNG(&Grid);
|
|
||||||
pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<int> point({0,0,0,0});
|
|
||||||
|
|
||||||
LatticeFermion src (&Grid); //random(pRNG,src);
|
|
||||||
SpinColourVectorD Sp;
|
|
||||||
for (unsigned int s = 0; s < Ns; ++s)
|
|
||||||
for (unsigned int c = 0; c < Nc; ++c)
|
|
||||||
Sp()(s)(c) = 1;
|
|
||||||
|
|
||||||
src = zero;
|
|
||||||
pokeSite(Sp,src,point);
|
|
||||||
|
|
||||||
LatticeFermion result(&Grid); result=zero;
|
|
||||||
LatticeFermion tmp(&Grid); tmp=zero;
|
|
||||||
|
|
||||||
// Gauge configuration
|
|
||||||
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
|
|
||||||
std::cout<<GridLogMessage<<"= Testing the laplacian operator on a point source "<<std::endl;
|
|
||||||
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
|
|
||||||
|
|
||||||
Laplacian<WilsonImplR> LaplaceOperator(src._grid);
|
|
||||||
LaplaceOperator.ImportGauge(Umu);
|
|
||||||
LaplaceOperator.M(src, result);
|
|
||||||
|
|
||||||
std::cout << "Source vector" << std::endl;
|
|
||||||
std::cout << src << std::endl;
|
|
||||||
|
|
||||||
std::cout << "Result vector" << std::endl;
|
|
||||||
std::cout << result << std::endl;
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
|
|
||||||
std::cout<<GridLogMessage<<"= Testing the laplacian smearing operator on a point source "<<std::endl;
|
|
||||||
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
|
|
||||||
|
|
||||||
LatticeFermion smeared (&Grid); smeared = src;
|
|
||||||
for (int smr = 0; smr < 10; ++smr)
|
|
||||||
{
|
|
||||||
LaplaceOperator.M(smeared, tmp);
|
|
||||||
smeared += 0.1*tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Smeared vector" << std::endl;
|
|
||||||
std::cout << smeared << std::endl;
|
|
||||||
|
|
||||||
// Norm of vector
|
|
||||||
LatticeComplex smr_norm(&Grid);
|
|
||||||
smr_norm = localNorm2(smeared);
|
|
||||||
std::cout << "Smeared vector norm" << std::endl;
|
|
||||||
std::cout << smr_norm << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
|
|||||||
double volume = latt_size[0] * latt_size[1] * latt_size[2] * latt_size[3];
|
double volume = latt_size[0] * latt_size[1] * latt_size[2] * latt_size[3];
|
||||||
|
|
||||||
GridCartesian Fine(latt_size, simd_layout, mpi_layout);
|
GridCartesian Fine(latt_size, simd_layout, mpi_layout);
|
||||||
GridRedBlackCartesian rbFine(&Fine);
|
GridRedBlackCartesian rbFine(latt_size, simd_layout, mpi_layout);
|
||||||
GridParallelRNG FineRNG(&Fine);
|
GridParallelRNG FineRNG(&Fine);
|
||||||
GridSerialRNG SerialRNG;
|
GridSerialRNG SerialRNG;
|
||||||
GridSerialRNG SerialRNG1;
|
GridSerialRNG SerialRNG1;
|
||||||
|
|||||||
@@ -1,241 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/core/Test_dwf_eofa_even_odd.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
template<class d>
|
|
||||||
struct scal {
|
|
||||||
d internal;
|
|
||||||
};
|
|
||||||
|
|
||||||
Gamma::Algebra Gmu [] = {
|
|
||||||
Gamma::Algebra::GammaX,
|
|
||||||
Gamma::Algebra::GammaY,
|
|
||||||
Gamma::Algebra::GammaZ,
|
|
||||||
Gamma::Algebra::GammaT
|
|
||||||
};
|
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
const int Ls = 8;
|
|
||||||
// GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
std::vector<int> seeds4({1,2,3,4});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
|
|
||||||
LatticeFermion src (FGrid); random(RNG5, src);
|
|
||||||
LatticeFermion phi (FGrid); random(RNG5, phi);
|
|
||||||
LatticeFermion chi (FGrid); random(RNG5, chi);
|
|
||||||
LatticeFermion result(FGrid); result = zero;
|
|
||||||
LatticeFermion ref (FGrid); ref = zero;
|
|
||||||
LatticeFermion tmp (FGrid); tmp = zero;
|
|
||||||
LatticeFermion err (FGrid); err = zero;
|
|
||||||
LatticeGaugeField Umu (UGrid); SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
std::vector<LatticeColourMatrix> U(4,UGrid);
|
|
||||||
|
|
||||||
// Only one non-zero (y)
|
|
||||||
Umu = zero;
|
|
||||||
for(int nn=0; nn<Nd; nn++){
|
|
||||||
random(RNG4, U[nn]);
|
|
||||||
if(nn>0){ U[nn] = zero; }
|
|
||||||
PokeIndex<LorentzIndex>(Umu, U[nn], nn);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD b = 2.5;
|
|
||||||
RealD c = 1.5;
|
|
||||||
RealD mq1 = 0.1;
|
|
||||||
RealD mq2 = 0.5;
|
|
||||||
RealD mq3 = 1.0;
|
|
||||||
RealD shift = 0.1234;
|
|
||||||
RealD M5 = 1.8;
|
|
||||||
int pm = 1;
|
|
||||||
MobiusEOFAFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mq1, mq2, mq3, shift, pm, M5, b, c);
|
|
||||||
|
|
||||||
LatticeFermion src_e (FrbGrid);
|
|
||||||
LatticeFermion src_o (FrbGrid);
|
|
||||||
LatticeFermion r_e (FrbGrid);
|
|
||||||
LatticeFermion r_o (FrbGrid);
|
|
||||||
LatticeFermion r_eo (FGrid);
|
|
||||||
LatticeFermion r_eeoo(FGrid);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Testing that Meo + Moe + Moo + Mee = Munprec " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
|
||||||
|
|
||||||
pickCheckerboard(Even, src_e, src);
|
|
||||||
pickCheckerboard(Odd, src_o, src);
|
|
||||||
|
|
||||||
Ddwf.Meooe(src_e, r_o); std::cout << GridLogMessage << "Applied Meo" << std::endl;
|
|
||||||
Ddwf.Meooe(src_o, r_e); std::cout << GridLogMessage << "Applied Moe" << std::endl;
|
|
||||||
setCheckerboard(r_eo, r_o);
|
|
||||||
setCheckerboard(r_eo, r_e);
|
|
||||||
|
|
||||||
Ddwf.Mooee(src_e, r_e); std::cout << GridLogMessage << "Applied Mee" << std::endl;
|
|
||||||
Ddwf.Mooee(src_o, r_o); std::cout << GridLogMessage << "Applied Moo" << std::endl;
|
|
||||||
setCheckerboard(r_eeoo, r_e);
|
|
||||||
setCheckerboard(r_eeoo, r_o);
|
|
||||||
|
|
||||||
r_eo = r_eo + r_eeoo;
|
|
||||||
Ddwf.M(src, ref);
|
|
||||||
|
|
||||||
// std::cout << GridLogMessage << r_eo << std::endl;
|
|
||||||
// std::cout << GridLogMessage << ref << std::endl;
|
|
||||||
|
|
||||||
err = ref - r_eo;
|
|
||||||
std::cout << GridLogMessage << "EO norm diff " << norm2(err) << " " << norm2(ref) << " " << norm2(r_eo) << std::endl;
|
|
||||||
|
|
||||||
LatticeComplex cerr(FGrid);
|
|
||||||
cerr = localInnerProduct(err,err);
|
|
||||||
// std::cout << GridLogMessage << cerr << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test Ddagger is the dagger of D by requiring " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= < phi | Deo | chi > * = < chi | Deo^dag| phi> " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
LatticeFermion chi_e (FrbGrid);
|
|
||||||
LatticeFermion chi_o (FrbGrid);
|
|
||||||
|
|
||||||
LatticeFermion dchi_e(FrbGrid);
|
|
||||||
LatticeFermion dchi_o(FrbGrid);
|
|
||||||
|
|
||||||
LatticeFermion phi_e (FrbGrid);
|
|
||||||
LatticeFermion phi_o (FrbGrid);
|
|
||||||
|
|
||||||
LatticeFermion dphi_e(FrbGrid);
|
|
||||||
LatticeFermion dphi_o(FrbGrid);
|
|
||||||
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
pickCheckerboard(Even, phi_e, phi);
|
|
||||||
pickCheckerboard(Odd , phi_o, phi);
|
|
||||||
|
|
||||||
Ddwf.Meooe (chi_e, dchi_o);
|
|
||||||
Ddwf.Meooe (chi_o, dchi_e);
|
|
||||||
Ddwf.MeooeDag(phi_e, dphi_o);
|
|
||||||
Ddwf.MeooeDag(phi_o, dphi_e);
|
|
||||||
|
|
||||||
ComplexD pDce = innerProduct(phi_e, dchi_e);
|
|
||||||
ComplexD pDco = innerProduct(phi_o, dchi_o);
|
|
||||||
ComplexD cDpe = innerProduct(chi_e, dphi_e);
|
|
||||||
ComplexD cDpo = innerProduct(chi_o, dphi_o);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
|
||||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDce-conj(cDpo) << std::endl;
|
|
||||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDco-conj(cDpe) << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test MeeInv Mee = 1 " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
|
|
||||||
Ddwf.Mooee (chi_e, src_e);
|
|
||||||
Ddwf.MooeeInv(src_e, phi_e);
|
|
||||||
|
|
||||||
Ddwf.Mooee (chi_o, src_o);
|
|
||||||
Ddwf.MooeeInv(src_o, phi_o);
|
|
||||||
|
|
||||||
setCheckerboard(phi, phi_e);
|
|
||||||
setCheckerboard(phi, phi_o);
|
|
||||||
|
|
||||||
err = phi - chi;
|
|
||||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test MeeInvDag MeeDag = 1 " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
|
|
||||||
Ddwf.MooeeDag (chi_e, src_e);
|
|
||||||
Ddwf.MooeeInvDag(src_e, phi_e);
|
|
||||||
|
|
||||||
Ddwf.MooeeDag (chi_o, src_o);
|
|
||||||
Ddwf.MooeeInvDag(src_o, phi_o);
|
|
||||||
|
|
||||||
setCheckerboard(phi, phi_e);
|
|
||||||
setCheckerboard(phi, phi_o);
|
|
||||||
|
|
||||||
err = phi - chi;
|
|
||||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
std::cout << GridLogMessage << "= Test MpcDagMpc is Hermitian " << std::endl;
|
|
||||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
|
||||||
|
|
||||||
random(RNG5, phi);
|
|
||||||
random(RNG5, chi);
|
|
||||||
pickCheckerboard(Even, chi_e, chi);
|
|
||||||
pickCheckerboard(Odd , chi_o, chi);
|
|
||||||
pickCheckerboard(Even, phi_e, phi);
|
|
||||||
pickCheckerboard(Odd , phi_o, phi);
|
|
||||||
RealD t1,t2;
|
|
||||||
|
|
||||||
SchurDiagMooeeOperator<MobiusEOFAFermionR,LatticeFermion> HermOpEO(Ddwf);
|
|
||||||
HermOpEO.MpcDagMpc(chi_e, dchi_e, t1, t2);
|
|
||||||
HermOpEO.MpcDagMpc(chi_o, dchi_o, t1, t2);
|
|
||||||
|
|
||||||
HermOpEO.MpcDagMpc(phi_e, dphi_e, t1, t2);
|
|
||||||
HermOpEO.MpcDagMpc(phi_o, dphi_o, t1, t2);
|
|
||||||
|
|
||||||
pDce = innerProduct(phi_e, dchi_e);
|
|
||||||
pDco = innerProduct(phi_o, dchi_o);
|
|
||||||
cDpe = innerProduct(chi_e, dphi_e);
|
|
||||||
cDpo = innerProduct(chi_o, dphi_o);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
|
||||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDco-conj(cDpo) << std::endl;
|
|
||||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDce-conj(cDpe) << std::endl;
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
|
||||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
|
||||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <Grid/Grid.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
// Parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Npoles = 12;
|
|
||||||
const RealD mf = 0.01;
|
|
||||||
const RealD mpv = 1.0;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
DomainWallEOFAFermionR Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5);
|
|
||||||
DomainWallEOFAFermionR Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5);
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (zero initial guess)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
|
||||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
|
||||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <Grid/Grid.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
typedef GparityWilsonImplR FermionImplPolicy;
|
|
||||||
typedef GparityDomainWallEOFAFermionR FermionAction;
|
|
||||||
typedef typename FermionAction::FermionField FermionField;
|
|
||||||
|
|
||||||
// Parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Npoles = 12;
|
|
||||||
const RealD mf = 0.01;
|
|
||||||
const RealD mpv = 1.0;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
// GparityDomainWallFermionR::ImplParams params;
|
|
||||||
FermionAction::ImplParams params;
|
|
||||||
FermionAction Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5, params);
|
|
||||||
FermionAction Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5, params);
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (zero initial guess)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
|
||||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
|
||||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <Grid/Grid.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
// Parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Npoles = 12;
|
|
||||||
const RealD b = 2.5;
|
|
||||||
const RealD c = 1.5;
|
|
||||||
const RealD mf = 0.01;
|
|
||||||
const RealD mpv = 1.0;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
MobiusEOFAFermionR Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5, b, c);
|
|
||||||
MobiusEOFAFermionR Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5, b, c);
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (zero initial guess)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
|
||||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
|
||||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <Grid/Grid.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
typedef GparityWilsonImplR FermionImplPolicy;
|
|
||||||
typedef GparityMobiusEOFAFermionR FermionAction;
|
|
||||||
typedef typename FermionAction::FermionField FermionField;
|
|
||||||
|
|
||||||
// Parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Npoles = 12;
|
|
||||||
const RealD b = 2.5;
|
|
||||||
const RealD c = 1.5;
|
|
||||||
const RealD mf = 0.01;
|
|
||||||
const RealD mpv = 1.0;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
FermionAction::ImplParams params;
|
|
||||||
FermionAction Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5, b, c, params);
|
|
||||||
FermionAction Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5, b, c, params);
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (zero initial guess)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
|
||||||
{
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
|
||||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
|
|
||||||
|
|
||||||
Meofa.refresh(Umu, RNG5);
|
|
||||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
// parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Nhits = 25;
|
|
||||||
const int max_iter = 5000;
|
|
||||||
const RealD mf = 0.1;
|
|
||||||
const RealD mb = 0.11;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
const RealD stop_tol = 1.0e-12;
|
|
||||||
|
|
||||||
RealD mean(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
|
||||||
return mean/RealD(N);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
|
||||||
return mean/RealD(N-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
|
||||||
{
|
|
||||||
int N = jacks.size();
|
|
||||||
RealD std(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
|
||||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
std::vector<RealD> jack_samples(N);
|
|
||||||
std::vector<RealD> jack_stats(2);
|
|
||||||
|
|
||||||
jack_stats[0] = mean(data);
|
|
||||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
|
||||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
|
||||||
return jack_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
|
||||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
// Initialize RHMC fermion operators
|
|
||||||
DomainWallFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5);
|
|
||||||
DomainWallFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5);
|
|
||||||
SchurDiagMooeeOperator<DomainWallFermionR, LatticeFermion> MdagM(Ddwf_f);
|
|
||||||
SchurDiagMooeeOperator<DomainWallFermionR, LatticeFermion> VdagV(Ddwf_b);
|
|
||||||
|
|
||||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
|
||||||
double lo = 0.0001;
|
|
||||||
double hi = 95.0;
|
|
||||||
int precision = 64;
|
|
||||||
int degree = 12;
|
|
||||||
AlgRemez remez(lo, hi, precision);
|
|
||||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
|
||||||
remez.generateApprox(degree, 1, 4);
|
|
||||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
|
||||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via RHMC
|
|
||||||
RealD scale = std::sqrt(0.5);
|
|
||||||
std::vector<RealD> rw_rhmc(Nhits);
|
|
||||||
ConjugateGradientMultiShift<LatticeFermion> msCG_V(max_iter, PowerQuarter);
|
|
||||||
ConjugateGradientMultiShift<LatticeFermion> msCG_M(max_iter, PowerNegQuarter);
|
|
||||||
std::cout.precision(12);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
LatticeFermion Phi (Ddwf_f.FermionGrid());
|
|
||||||
LatticeFermion PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
|
||||||
std::vector<LatticeFermion> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
|
||||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
|
||||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize EOFA fermion operators
|
|
||||||
RealD shift_L = 0.0;
|
|
||||||
RealD shift_R = -1.0;
|
|
||||||
int pm = 1;
|
|
||||||
DomainWallEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5);
|
|
||||||
DomainWallEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5);
|
|
||||||
MdagMLinearOperator<DomainWallEOFAFermionR, LatticeFermion> LdagL(Deofa_L);
|
|
||||||
MdagMLinearOperator<DomainWallEOFAFermionR, LatticeFermion> RdagR(Deofa_R);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via EOFA
|
|
||||||
RealD k = Deofa_L.k;
|
|
||||||
std::vector<RealD> rw_eofa(Nhits);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(stop_tol, max_iter);
|
|
||||||
SchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
LatticeFermion Phi (Deofa_L.FermionGrid());
|
|
||||||
LatticeFermion spProj_Phi(Deofa_L.FermionGrid());
|
|
||||||
std::vector<LatticeFermion> tmp(2, Deofa_L.FermionGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
// LH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
|
||||||
Deofa_L.Omega(tmp[0], tmp[1], -1, 1);
|
|
||||||
rw_eofa[hit] = -k*innerProduct(spProj_Phi,tmp[1]).real();
|
|
||||||
|
|
||||||
// RH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
|
||||||
Deofa_R.Omega(tmp[0], tmp[1], 1, 1);
|
|
||||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[1]).real();
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
|
||||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
|
||||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
|
||||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_reweight_dwf_eofa_gparity.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
typedef typename GparityDomainWallFermionR::FermionField FermionField;
|
|
||||||
|
|
||||||
// parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Nhits = 10;
|
|
||||||
const int max_iter = 5000;
|
|
||||||
const RealD mf = 0.1;
|
|
||||||
const RealD mb = 0.11;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
const RealD stop_tol = 1.0e-12;
|
|
||||||
|
|
||||||
RealD mean(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
|
||||||
return mean/RealD(N);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
|
||||||
return mean/RealD(N-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
|
||||||
{
|
|
||||||
int N = jacks.size();
|
|
||||||
RealD std(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
|
||||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
std::vector<RealD> jack_samples(N);
|
|
||||||
std::vector<RealD> jack_stats(2);
|
|
||||||
|
|
||||||
jack_stats[0] = mean(data);
|
|
||||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
|
||||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
|
||||||
return jack_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
|
||||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
// Initialize RHMC fermion operators
|
|
||||||
GparityDomainWallFermionR::ImplParams params;
|
|
||||||
GparityDomainWallFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, params);
|
|
||||||
GparityDomainWallFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, params);
|
|
||||||
SchurDiagMooeeOperator<GparityDomainWallFermionR, FermionField> MdagM(Ddwf_f);
|
|
||||||
SchurDiagMooeeOperator<GparityDomainWallFermionR, FermionField> VdagV(Ddwf_b);
|
|
||||||
|
|
||||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
|
||||||
double lo = 0.0001;
|
|
||||||
double hi = 95.0;
|
|
||||||
int precision = 64;
|
|
||||||
int degree = 12;
|
|
||||||
AlgRemez remez(lo, hi, precision);
|
|
||||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
|
||||||
remez.generateApprox(degree, 1, 4);
|
|
||||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
|
||||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via RHMC
|
|
||||||
RealD scale = std::sqrt(0.5);
|
|
||||||
std::vector<RealD> rw_rhmc(Nhits);
|
|
||||||
ConjugateGradientMultiShift<FermionField> msCG_V(max_iter, PowerQuarter);
|
|
||||||
ConjugateGradientMultiShift<FermionField> msCG_M(max_iter, PowerNegQuarter);
|
|
||||||
std::cout.precision(12);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
FermionField Phi (Ddwf_f.FermionGrid());
|
|
||||||
FermionField PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
|
||||||
std::vector<FermionField> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
|
||||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
|
||||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize EOFA fermion operators
|
|
||||||
RealD shift_L = 0.0;
|
|
||||||
RealD shift_R = -1.0;
|
|
||||||
int pm = 1;
|
|
||||||
GparityDomainWallEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, params);
|
|
||||||
GparityDomainWallEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, params);
|
|
||||||
MdagMLinearOperator<GparityDomainWallEOFAFermionR, FermionField> LdagL(Deofa_L);
|
|
||||||
MdagMLinearOperator<GparityDomainWallEOFAFermionR, FermionField> RdagR(Deofa_R);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via EOFA
|
|
||||||
RealD k = Deofa_L.k;
|
|
||||||
std::vector<RealD> rw_eofa(Nhits);
|
|
||||||
ConjugateGradient<FermionField> CG(stop_tol, max_iter);
|
|
||||||
SchurRedBlackDiagMooeeSolve<FermionField> SchurSolver(CG);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
FermionField Phi (Deofa_L.FermionGrid());
|
|
||||||
FermionField spProj_Phi(Deofa_L.FermionGrid());
|
|
||||||
std::vector<FermionField> tmp(2, Deofa_L.FermionGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
// LH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
|
||||||
Deofa_L.Omega(tmp[0], tmp[1], -1, 1);
|
|
||||||
rw_eofa[hit] = -k*innerProduct(spProj_Phi,tmp[1]).real();
|
|
||||||
|
|
||||||
// RH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
|
||||||
Deofa_R.Omega(tmp[0], tmp[1], 1, 1);
|
|
||||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[1]).real();
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
|
||||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
|
||||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
|
||||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
// parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Nhits = 10;
|
|
||||||
const int max_iter = 5000;
|
|
||||||
const RealD b = 2.5;
|
|
||||||
const RealD c = 1.5;
|
|
||||||
const RealD mf = 0.1;
|
|
||||||
const RealD mb = 0.11;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
const RealD stop_tol = 1.0e-12;
|
|
||||||
|
|
||||||
RealD mean(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
|
||||||
return mean/RealD(N);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
|
||||||
return mean/RealD(N-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
|
||||||
{
|
|
||||||
int N = jacks.size();
|
|
||||||
RealD std(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
|
||||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
std::vector<RealD> jack_samples(N);
|
|
||||||
std::vector<RealD> jack_stats(2);
|
|
||||||
|
|
||||||
jack_stats[0] = mean(data);
|
|
||||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
|
||||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
|
||||||
return jack_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
|
||||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
// Initialize RHMC fermion operators
|
|
||||||
MobiusFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, b, c);
|
|
||||||
MobiusFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, b, c);
|
|
||||||
SchurDiagMooeeOperator<MobiusFermionR, LatticeFermion> MdagM(Ddwf_f);
|
|
||||||
SchurDiagMooeeOperator<MobiusFermionR, LatticeFermion> VdagV(Ddwf_b);
|
|
||||||
|
|
||||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
|
||||||
double lo = 0.0001;
|
|
||||||
double hi = 95.0;
|
|
||||||
int precision = 64;
|
|
||||||
int degree = 12;
|
|
||||||
AlgRemez remez(lo, hi, precision);
|
|
||||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
|
||||||
remez.generateApprox(degree, 1, 4);
|
|
||||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
|
||||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via RHMC
|
|
||||||
RealD scale = std::sqrt(0.5);
|
|
||||||
std::vector<RealD> rw_rhmc(Nhits);
|
|
||||||
ConjugateGradientMultiShift<LatticeFermion> msCG_V(max_iter, PowerQuarter);
|
|
||||||
ConjugateGradientMultiShift<LatticeFermion> msCG_M(max_iter, PowerNegQuarter);
|
|
||||||
std::cout.precision(12);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
LatticeFermion Phi (Ddwf_f.FermionGrid());
|
|
||||||
LatticeFermion PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
|
||||||
std::vector<LatticeFermion> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
|
||||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
|
||||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize EOFA fermion operators
|
|
||||||
RealD shift_L = 0.0;
|
|
||||||
RealD shift_R = -1.0;
|
|
||||||
int pm = 1;
|
|
||||||
MobiusEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, b, c);
|
|
||||||
MobiusEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, b, c);
|
|
||||||
MdagMLinearOperator<MobiusEOFAFermionR, LatticeFermion> LdagL(Deofa_L);
|
|
||||||
MdagMLinearOperator<MobiusEOFAFermionR, LatticeFermion> RdagR(Deofa_R);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via EOFA
|
|
||||||
RealD k = Deofa_L.k;
|
|
||||||
std::vector<RealD> rw_eofa(Nhits);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(stop_tol, max_iter);
|
|
||||||
SchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
|
|
||||||
|
|
||||||
// Compute -log(Z), where: ( RHMC det ratio ) = Z * ( EOFA det ratio )
|
|
||||||
RealD Z = std::pow(b+c+1.0,Ls) + mf*std::pow(b+c-1.0,Ls);
|
|
||||||
Z /= std::pow(b+c+1.0,Ls) + mb*std::pow(b+c-1.0,Ls);
|
|
||||||
Z = -12.0*grid_dim[0]*grid_dim[1]*grid_dim[2]*grid_dim[3]*std::log(Z);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
LatticeFermion Phi (Deofa_L.FermionGrid());
|
|
||||||
LatticeFermion spProj_Phi(Deofa_L.FermionGrid());
|
|
||||||
std::vector<LatticeFermion> tmp(2, Deofa_L.FermionGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
// LH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
|
||||||
Deofa_L.Dtilde(tmp[0], tmp[1]);
|
|
||||||
Deofa_L.Omega(tmp[1], tmp[0], -1, 1);
|
|
||||||
rw_eofa[hit] = Z - k*innerProduct(spProj_Phi,tmp[0]).real();
|
|
||||||
|
|
||||||
// RH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
|
||||||
Deofa_R.Dtilde(tmp[0], tmp[1]);
|
|
||||||
Deofa_R.Omega(tmp[1], tmp[0], 1, 1);
|
|
||||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[0]).real();
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
|
||||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
|
||||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
|
||||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
typedef typename GparityDomainWallFermionR::FermionField FermionField;
|
|
||||||
|
|
||||||
// parameters for test
|
|
||||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
|
||||||
const int Ls = 8;
|
|
||||||
const int Nhits = 10;
|
|
||||||
const int max_iter = 5000;
|
|
||||||
const RealD b = 2.5;
|
|
||||||
const RealD c = 1.5;
|
|
||||||
const RealD mf = 0.1;
|
|
||||||
const RealD mb = 0.11;
|
|
||||||
const RealD M5 = 1.8;
|
|
||||||
const RealD stop_tol = 1.0e-12;
|
|
||||||
|
|
||||||
RealD mean(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
|
||||||
return mean/RealD(N);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
RealD mean(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
|
||||||
return mean/RealD(N-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
|
||||||
{
|
|
||||||
int N = jacks.size();
|
|
||||||
RealD std(0.0);
|
|
||||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
|
||||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
|
||||||
{
|
|
||||||
int N = data.size();
|
|
||||||
std::vector<RealD> jack_samples(N);
|
|
||||||
std::vector<RealD> jack_stats(2);
|
|
||||||
|
|
||||||
jack_stats[0] = mean(data);
|
|
||||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
|
||||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
|
||||||
return jack_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
// Initialize spacetime grid
|
|
||||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
|
||||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
|
||||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
|
||||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Set up RNGs
|
|
||||||
std::vector<int> seeds4({1, 2, 3, 4});
|
|
||||||
std::vector<int> seeds5({5, 6, 7, 8});
|
|
||||||
GridParallelRNG RNG5(FGrid);
|
|
||||||
RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid);
|
|
||||||
RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
// Random gauge field
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4, Umu);
|
|
||||||
|
|
||||||
// Initialize RHMC fermion operators
|
|
||||||
GparityDomainWallFermionR::ImplParams params;
|
|
||||||
GparityMobiusFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, b, c, params);
|
|
||||||
GparityMobiusFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, b, c, params);
|
|
||||||
SchurDiagMooeeOperator<GparityMobiusFermionR, FermionField> MdagM(Ddwf_f);
|
|
||||||
SchurDiagMooeeOperator<GparityMobiusFermionR, FermionField> VdagV(Ddwf_b);
|
|
||||||
|
|
||||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
|
||||||
double lo = 0.0001;
|
|
||||||
double hi = 95.0;
|
|
||||||
int precision = 64;
|
|
||||||
int degree = 12;
|
|
||||||
AlgRemez remez(lo, hi, precision);
|
|
||||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
|
||||||
remez.generateApprox(degree, 1, 4);
|
|
||||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
|
||||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via RHMC
|
|
||||||
RealD scale = std::sqrt(0.5);
|
|
||||||
std::vector<RealD> rw_rhmc(Nhits);
|
|
||||||
ConjugateGradientMultiShift<FermionField> msCG_V(max_iter, PowerQuarter);
|
|
||||||
ConjugateGradientMultiShift<FermionField> msCG_M(max_iter, PowerNegQuarter);
|
|
||||||
std::cout.precision(12);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
FermionField Phi (Ddwf_f.FermionGrid());
|
|
||||||
FermionField PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
|
||||||
std::vector<FermionField> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
|
||||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
|
||||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize EOFA fermion operators
|
|
||||||
RealD shift_L = 0.0;
|
|
||||||
RealD shift_R = -1.0;
|
|
||||||
int pm = 1;
|
|
||||||
GparityMobiusEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, b, c, params);
|
|
||||||
GparityMobiusEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, b, c, params);
|
|
||||||
MdagMLinearOperator<GparityMobiusEOFAFermionR, FermionField> LdagL(Deofa_L);
|
|
||||||
MdagMLinearOperator<GparityMobiusEOFAFermionR, FermionField> RdagR(Deofa_R);
|
|
||||||
|
|
||||||
// Stochastically estimate reweighting factor via EOFA
|
|
||||||
RealD k = Deofa_L.k;
|
|
||||||
std::vector<RealD> rw_eofa(Nhits);
|
|
||||||
ConjugateGradient<FermionField> CG(stop_tol, max_iter);
|
|
||||||
SchurRedBlackDiagMooeeSolve<FermionField> SchurSolver(CG);
|
|
||||||
|
|
||||||
// Compute -log(Z), where: ( RHMC det ratio ) = Z * ( EOFA det ratio )
|
|
||||||
RealD Z = std::pow(b+c+1.0,Ls) + mf*std::pow(b+c-1.0,Ls);
|
|
||||||
Z /= std::pow(b+c+1.0,Ls) + mb*std::pow(b+c-1.0,Ls);
|
|
||||||
Z = -12.0*grid_dim[0]*grid_dim[1]*grid_dim[2]*grid_dim[3]*std::log(Z);
|
|
||||||
|
|
||||||
for(int hit=0; hit<Nhits; hit++){
|
|
||||||
|
|
||||||
// Gaussian source
|
|
||||||
FermionField Phi (Deofa_L.FermionGrid());
|
|
||||||
FermionField spProj_Phi(Deofa_L.FermionGrid());
|
|
||||||
std::vector<FermionField> tmp(2, Deofa_L.FermionGrid());
|
|
||||||
gaussian(RNG5, Phi);
|
|
||||||
Phi = Phi*scale;
|
|
||||||
|
|
||||||
// evaluate -log(rw)
|
|
||||||
// LH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
|
||||||
Deofa_L.Dtilde(tmp[0], tmp[1]);
|
|
||||||
Deofa_L.Omega(tmp[1], tmp[0], -1, 1);
|
|
||||||
rw_eofa[hit] = 2.0*Z - k*innerProduct(spProj_Phi,tmp[0]).real();
|
|
||||||
|
|
||||||
// RH term
|
|
||||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
|
||||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
|
||||||
G5R5(tmp[1], tmp[0]);
|
|
||||||
tmp[0] = zero;
|
|
||||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
|
||||||
Deofa_R.Dtilde(tmp[0], tmp[1]);
|
|
||||||
Deofa_R.Omega(tmp[1], tmp[0], 1, 1);
|
|
||||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[0]).real();
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl;
|
|
||||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
|
||||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
|
||||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
|
||||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
|
||||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
std::vector<int> latt_size = GridDefaultLatt();
|
|
||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
|
||||||
|
|
||||||
const int Ls = 8;
|
|
||||||
|
|
||||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Want a different conf at every run
|
|
||||||
// First create an instance of an engine.
|
|
||||||
std::random_device rnd_device;
|
|
||||||
// Specify the engine and distribution.
|
|
||||||
std::mt19937 mersenne_engine(rnd_device());
|
|
||||||
std::uniform_int_distribution<int> dist(1, 100);
|
|
||||||
|
|
||||||
auto gen = std::bind(dist, mersenne_engine);
|
|
||||||
std::vector<int> seeds4(4);
|
|
||||||
generate(begin(seeds4), end(seeds4), gen);
|
|
||||||
|
|
||||||
//std::vector<int> seeds4({1,2,3,5});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
LatticeFermion phi (FGrid); gaussian(RNG5, phi);
|
|
||||||
LatticeFermion Mphi (FGrid);
|
|
||||||
LatticeFermion MphiPrime (FGrid);
|
|
||||||
|
|
||||||
LatticeGaugeField U(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4,U);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Unmodified matrix element
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD mf = 0.01;
|
|
||||||
RealD mb = 1.0;
|
|
||||||
RealD M5 = 1.8;
|
|
||||||
DomainWallEOFAFermionR Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5);
|
|
||||||
DomainWallEOFAFermionR Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5);
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
|
|
||||||
|
|
||||||
Meofa.refresh(U, RNG5);
|
|
||||||
RealD S = Meofa.S(U); // pdag M p
|
|
||||||
|
|
||||||
// get the deriv of phidag M phi with respect to "U"
|
|
||||||
LatticeGaugeField UdSdU(UGrid);
|
|
||||||
Meofa.deriv(U, UdSdU);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Modify the gauge field a little
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD dt = 0.0001;
|
|
||||||
|
|
||||||
LatticeColourMatrix mommu(UGrid);
|
|
||||||
LatticeColourMatrix forcemu(UGrid);
|
|
||||||
LatticeGaugeField mom(UGrid);
|
|
||||||
LatticeGaugeField Uprime(UGrid);
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
|
|
||||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
|
||||||
|
|
||||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
|
||||||
|
|
||||||
// fourth order exponential approx
|
|
||||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
|
||||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Ddwf.ImportGauge(Uprime);
|
|
||||||
Ddwf.M (phi,MphiPrime);
|
|
||||||
|
|
||||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
|
||||||
RealD Sprime = Meofa.S(Uprime);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Use derivative to estimate dS
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
|
|
||||||
LatticeComplex dS(UGrid);
|
|
||||||
dS = zero;
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = Ta(mommu)*2.0;
|
|
||||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
|
||||||
|
|
||||||
// Update PF action density
|
|
||||||
dS = dS + trace(mommu*forcemu)*dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComplexD dSpred = sum(dS);
|
|
||||||
|
|
||||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
|
||||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
|
||||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
|
||||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
|
||||||
printf("\nS = %1.15e\n", S);
|
|
||||||
printf("Sprime = %1.15e\n", Sprime);
|
|
||||||
printf("dS = %1.15e\n", Sprime - S);
|
|
||||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
|
||||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
|
||||||
|
|
||||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Done" << std::endl;
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
typedef GparityWilsonImplR FermionImplPolicy;
|
|
||||||
typedef GparityDomainWallEOFAFermionR FermionAction;
|
|
||||||
typedef typename FermionAction::FermionField FermionField;
|
|
||||||
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
std::vector<int> latt_size = GridDefaultLatt();
|
|
||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
|
||||||
|
|
||||||
const int Ls = 8;
|
|
||||||
|
|
||||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Want a different conf at every run
|
|
||||||
// First create an instance of an engine.
|
|
||||||
std::random_device rnd_device;
|
|
||||||
// Specify the engine and distribution.
|
|
||||||
std::mt19937 mersenne_engine(rnd_device());
|
|
||||||
std::uniform_int_distribution<int> dist(1, 100);
|
|
||||||
|
|
||||||
auto gen = std::bind(dist, mersenne_engine);
|
|
||||||
std::vector<int> seeds4(4);
|
|
||||||
generate(begin(seeds4), end(seeds4), gen);
|
|
||||||
|
|
||||||
//std::vector<int> seeds4({1,2,3,5});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
FermionField phi (FGrid); gaussian(RNG5, phi);
|
|
||||||
FermionField Mphi (FGrid);
|
|
||||||
FermionField MphiPrime (FGrid);
|
|
||||||
|
|
||||||
LatticeGaugeField U(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4,U);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Unmodified matrix element
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD mf = 0.01;
|
|
||||||
RealD mb = 1.0;
|
|
||||||
RealD M5 = 1.8;
|
|
||||||
FermionAction::ImplParams params;
|
|
||||||
FermionAction Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, params);
|
|
||||||
FermionAction Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, params);
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
|
||||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
|
|
||||||
|
|
||||||
Meofa.refresh(U, RNG5);
|
|
||||||
RealD S = Meofa.S(U); // pdag M p
|
|
||||||
|
|
||||||
// get the deriv of phidag M phi with respect to "U"
|
|
||||||
LatticeGaugeField UdSdU(UGrid);
|
|
||||||
Meofa.deriv(U, UdSdU);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Modify the gauge field a little
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD dt = 0.0001;
|
|
||||||
|
|
||||||
LatticeColourMatrix mommu(UGrid);
|
|
||||||
LatticeColourMatrix forcemu(UGrid);
|
|
||||||
LatticeGaugeField mom(UGrid);
|
|
||||||
LatticeGaugeField Uprime(UGrid);
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
|
|
||||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
|
||||||
|
|
||||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
|
||||||
|
|
||||||
// fourth order exponential approx
|
|
||||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
|
||||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Ddwf.ImportGauge(Uprime);
|
|
||||||
Ddwf.M (phi,MphiPrime);
|
|
||||||
|
|
||||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
|
||||||
RealD Sprime = Meofa.S(Uprime);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Use derivative to estimate dS
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
|
|
||||||
LatticeComplex dS(UGrid);
|
|
||||||
dS = zero;
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = Ta(mommu)*2.0;
|
|
||||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
|
||||||
|
|
||||||
// Update PF action density
|
|
||||||
dS = dS + trace(mommu*forcemu)*dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComplexD dSpred = sum(dS);
|
|
||||||
|
|
||||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
|
||||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
|
||||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
|
||||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
|
||||||
printf("\nS = %1.15e\n", S);
|
|
||||||
printf("Sprime = %1.15e\n", Sprime);
|
|
||||||
printf("dS = %1.15e\n", Sprime - S);
|
|
||||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
|
||||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
|
||||||
|
|
||||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Done" << std::endl;
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
|
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
|
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -1,166 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
std::vector<int> latt_size = GridDefaultLatt();
|
|
||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
|
||||||
|
|
||||||
const int Ls = 8;
|
|
||||||
|
|
||||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Want a different conf at every run
|
|
||||||
// First create an instance of an engine.
|
|
||||||
std::random_device rnd_device;
|
|
||||||
// Specify the engine and distribution.
|
|
||||||
std::mt19937 mersenne_engine(rnd_device());
|
|
||||||
std::uniform_int_distribution<int> dist(1, 100);
|
|
||||||
|
|
||||||
auto gen = std::bind(dist, mersenne_engine);
|
|
||||||
std::vector<int> seeds4(4);
|
|
||||||
generate(begin(seeds4), end(seeds4), gen);
|
|
||||||
|
|
||||||
//std::vector<int> seeds4({1,2,3,5});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
LatticeFermion phi (FGrid); gaussian(RNG5, phi);
|
|
||||||
LatticeFermion Mphi (FGrid);
|
|
||||||
LatticeFermion MphiPrime (FGrid);
|
|
||||||
|
|
||||||
LatticeGaugeField U(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4,U);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Unmodified matrix element
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD b = 2.5;
|
|
||||||
RealD c = 1.5;
|
|
||||||
RealD mf = 0.01;
|
|
||||||
RealD mb = 1.0;
|
|
||||||
RealD M5 = 1.8;
|
|
||||||
MobiusEOFAFermionR Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, b, c);
|
|
||||||
MobiusEOFAFermionR Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, b, c);
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
|
||||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
|
|
||||||
|
|
||||||
Meofa.refresh(U, RNG5);
|
|
||||||
RealD S = Meofa.S(U); // pdag M p
|
|
||||||
|
|
||||||
// get the deriv of phidag M phi with respect to "U"
|
|
||||||
LatticeGaugeField UdSdU(UGrid);
|
|
||||||
Meofa.deriv(U, UdSdU);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Modify the gauge field a little
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD dt = 0.0001;
|
|
||||||
|
|
||||||
LatticeColourMatrix mommu(UGrid);
|
|
||||||
LatticeColourMatrix forcemu(UGrid);
|
|
||||||
LatticeGaugeField mom(UGrid);
|
|
||||||
LatticeGaugeField Uprime(UGrid);
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
|
|
||||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
|
||||||
|
|
||||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
|
||||||
|
|
||||||
// fourth order exponential approx
|
|
||||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
|
||||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Ddwf.ImportGauge(Uprime);
|
|
||||||
Ddwf.M (phi,MphiPrime);
|
|
||||||
|
|
||||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
|
||||||
RealD Sprime = Meofa.S(Uprime);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Use derivative to estimate dS
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
|
|
||||||
LatticeComplex dS(UGrid);
|
|
||||||
dS = zero;
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = Ta(mommu)*2.0;
|
|
||||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
|
||||||
|
|
||||||
// Update PF action density
|
|
||||||
dS = dS + trace(mommu*forcemu)*dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComplexD dSpred = sum(dS);
|
|
||||||
|
|
||||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
|
||||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
|
||||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
|
||||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
|
||||||
printf("\nS = %1.15e\n", S);
|
|
||||||
printf("Sprime = %1.15e\n", Sprime);
|
|
||||||
printf("dS = %1.15e\n", Sprime - S);
|
|
||||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
|
||||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
|
||||||
|
|
||||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Done" << std::endl;
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
|
||||||
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
||||||
Author: David Murphy <dmurphy@phys.columbia.edu>
|
|
||||||
|
|
||||||
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;
|
|
||||||
using namespace Grid::QCD;
|
|
||||||
|
|
||||||
typedef GparityWilsonImplR FermionImplPolicy;
|
|
||||||
typedef GparityMobiusEOFAFermionR FermionAction;
|
|
||||||
typedef typename FermionAction::FermionField FermionField;
|
|
||||||
|
|
||||||
int main (int argc, char** argv)
|
|
||||||
{
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
|
|
||||||
std::vector<int> latt_size = GridDefaultLatt();
|
|
||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
|
||||||
|
|
||||||
const int Ls = 8;
|
|
||||||
|
|
||||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
|
||||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
|
||||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
|
||||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
|
||||||
|
|
||||||
// Want a different conf at every run
|
|
||||||
// First create an instance of an engine.
|
|
||||||
std::random_device rnd_device;
|
|
||||||
// Specify the engine and distribution.
|
|
||||||
std::mt19937 mersenne_engine(rnd_device());
|
|
||||||
std::uniform_int_distribution<int> dist(1, 100);
|
|
||||||
|
|
||||||
auto gen = std::bind(dist, mersenne_engine);
|
|
||||||
std::vector<int> seeds4(4);
|
|
||||||
generate(begin(seeds4), end(seeds4), gen);
|
|
||||||
|
|
||||||
//std::vector<int> seeds4({1,2,3,5});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
|
||||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
|
||||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
|
||||||
|
|
||||||
FermionField phi (FGrid); gaussian(RNG5, phi);
|
|
||||||
FermionField Mphi (FGrid);
|
|
||||||
FermionField MphiPrime (FGrid);
|
|
||||||
|
|
||||||
LatticeGaugeField U(UGrid);
|
|
||||||
SU3::HotConfiguration(RNG4,U);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Unmodified matrix element
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD b = 2.5;
|
|
||||||
RealD c = 1.5;
|
|
||||||
RealD mf = 0.01;
|
|
||||||
RealD mb = 1.0;
|
|
||||||
RealD M5 = 1.8;
|
|
||||||
FermionAction::ImplParams params;
|
|
||||||
FermionAction Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, b, c, params);
|
|
||||||
FermionAction Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, b, c, params);
|
|
||||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
|
||||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
|
||||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
|
|
||||||
|
|
||||||
Meofa.refresh(U, RNG5);
|
|
||||||
RealD S = Meofa.S(U); // pdag M p
|
|
||||||
|
|
||||||
// get the deriv of phidag M phi with respect to "U"
|
|
||||||
LatticeGaugeField UdSdU(UGrid);
|
|
||||||
Meofa.deriv(U, UdSdU);
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
// Modify the gauge field a little
|
|
||||||
////////////////////////////////////
|
|
||||||
RealD dt = 0.0001;
|
|
||||||
|
|
||||||
LatticeColourMatrix mommu(UGrid);
|
|
||||||
LatticeColourMatrix forcemu(UGrid);
|
|
||||||
LatticeGaugeField mom(UGrid);
|
|
||||||
LatticeGaugeField Uprime(UGrid);
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
|
|
||||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
|
||||||
|
|
||||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
|
||||||
|
|
||||||
// fourth order exponential approx
|
|
||||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
|
||||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
|
||||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Ddwf.ImportGauge(Uprime);
|
|
||||||
Ddwf.M (phi,MphiPrime);
|
|
||||||
|
|
||||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
|
||||||
RealD Sprime = Meofa.S(Uprime);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Use derivative to estimate dS
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
|
|
||||||
LatticeComplex dS(UGrid);
|
|
||||||
dS = zero;
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = Ta(mommu)*2.0;
|
|
||||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int mu=0; mu<Nd; mu++){
|
|
||||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
|
||||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
|
||||||
|
|
||||||
// Update PF action density
|
|
||||||
dS = dS + trace(mommu*forcemu)*dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
ComplexD dSpred = sum(dS);
|
|
||||||
|
|
||||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
|
||||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
|
||||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
|
||||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
|
||||||
printf("\nS = %1.15e\n", S);
|
|
||||||
printf("Sprime = %1.15e\n", Sprime);
|
|
||||||
printf("dS = %1.15e\n", Sprime - S);
|
|
||||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
|
||||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
|
||||||
|
|
||||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << "Done" << std::endl;
|
|
||||||
Grid_finalize();
|
|
||||||
}
|
|
||||||
@@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
|
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
|||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
|
|
||||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|||||||
@@ -1,195 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: tests/hadrons/Test_hadrons_meson_3pt.cc
|
|
||||||
|
|
||||||
Copyright (C) 2015
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
|
||||||
|
|
||||||
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.
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include <Grid/Hadrons/Application.hpp>
|
|
||||||
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace Hadrons;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
// initialization //////////////////////////////////////////////////////////
|
|
||||||
Grid_init(&argc, &argv);
|
|
||||||
HadronsLogError.Active(GridLogError.isActive());
|
|
||||||
HadronsLogWarning.Active(GridLogWarning.isActive());
|
|
||||||
HadronsLogMessage.Active(GridLogMessage.isActive());
|
|
||||||
HadronsLogIterative.Active(GridLogIterative.isActive());
|
|
||||||
HadronsLogDebug.Active(GridLogDebug.isActive());
|
|
||||||
LOG(Message) << "Grid initialized" << std::endl;
|
|
||||||
|
|
||||||
// run setup ///////////////////////////////////////////////////////////////
|
|
||||||
Application application;
|
|
||||||
std::vector<std::string> flavour = {"l", "s", "c1", "c2", "c3"};
|
|
||||||
std::vector<double> mass = {.01, .04, .2 , .25 , .3 };
|
|
||||||
unsigned int nt = GridDefaultLatt()[Tp];
|
|
||||||
|
|
||||||
// global parameters
|
|
||||||
Application::GlobalPar globalPar;
|
|
||||||
globalPar.trajCounter.start = 1500;
|
|
||||||
globalPar.trajCounter.end = 1520;
|
|
||||||
globalPar.trajCounter.step = 20;
|
|
||||||
globalPar.seed = "1 2 3 4";
|
|
||||||
globalPar.genetic.maxGen = 1000;
|
|
||||||
globalPar.genetic.maxCstGen = 200;
|
|
||||||
globalPar.genetic.popSize = 20;
|
|
||||||
globalPar.genetic.mutationRate = .1;
|
|
||||||
application.setPar(globalPar);
|
|
||||||
|
|
||||||
|
|
||||||
// gauge field
|
|
||||||
application.createModule<MGauge::Unit>("gauge");
|
|
||||||
|
|
||||||
// set fermion boundary conditions to be periodic space, antiperiodic time.
|
|
||||||
std::string boundary = "1 1 1 -1";
|
|
||||||
|
|
||||||
// sink
|
|
||||||
MSink::Point::Par sinkPar;
|
|
||||||
sinkPar.mom = "0 0 0";
|
|
||||||
application.createModule<MSink::ScalarPoint>("sink", sinkPar);
|
|
||||||
for (unsigned int i = 0; i < flavour.size(); ++i)
|
|
||||||
{
|
|
||||||
// actions
|
|
||||||
MAction::DWF::Par actionPar;
|
|
||||||
actionPar.gauge = "gauge";
|
|
||||||
actionPar.Ls = 12;
|
|
||||||
actionPar.M5 = 1.8;
|
|
||||||
actionPar.mass = mass[i];
|
|
||||||
actionPar.boundary = boundary;
|
|
||||||
application.createModule<MAction::DWF>("DWF_" + flavour[i], actionPar);
|
|
||||||
|
|
||||||
// solvers
|
|
||||||
MSolver::RBPrecCG::Par solverPar;
|
|
||||||
solverPar.action = "DWF_" + flavour[i];
|
|
||||||
solverPar.residual = 1.0e-8;
|
|
||||||
application.createModule<MSolver::RBPrecCG>("CG_" + flavour[i],
|
|
||||||
solverPar);
|
|
||||||
}
|
|
||||||
for (unsigned int t = 0; t < nt; t += 1)
|
|
||||||
{
|
|
||||||
std::string srcName;
|
|
||||||
std::string lapName;
|
|
||||||
std::vector<std::string> qName;
|
|
||||||
std::vector<std::vector<std::string>> seqName;
|
|
||||||
|
|
||||||
// Z2 source
|
|
||||||
MSource::Z2::Par z2Par;
|
|
||||||
z2Par.tA = t;
|
|
||||||
z2Par.tB = t;
|
|
||||||
srcName = "z2_" + std::to_string(t);
|
|
||||||
application.createModule<MSource::Z2>(srcName, z2Par);
|
|
||||||
|
|
||||||
// Example of smearing of the source
|
|
||||||
MSource::LaplaceSmearing::Par LapPar;
|
|
||||||
LapPar.N = 10;
|
|
||||||
LapPar.alpha = 0.1;
|
|
||||||
LapPar.source = srcName;
|
|
||||||
LapPar.gauge = "gauge";
|
|
||||||
lapName = "z2smr_" + std::to_string(t);
|
|
||||||
application.createModule<MSource::LaplaceSmearing>(lapName, LapPar);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < flavour.size(); ++i)
|
|
||||||
{
|
|
||||||
// sequential sources
|
|
||||||
MSource::SeqGamma::Par seqPar;
|
|
||||||
qName.push_back("QZ2_" + flavour[i] + "_" + std::to_string(t));
|
|
||||||
seqPar.q = qName[i];
|
|
||||||
seqPar.tA = (t + nt/4) % nt;
|
|
||||||
seqPar.tB = (t + nt/4) % nt;
|
|
||||||
seqPar.mom = "1. 0. 0. 0.";
|
|
||||||
seqName.push_back(std::vector<std::string>(Nd));
|
|
||||||
for (unsigned int mu = 0; mu < Nd; ++mu)
|
|
||||||
{
|
|
||||||
seqPar.gamma = 0x1 << mu;
|
|
||||||
seqName[i][mu] = "G" + std::to_string(seqPar.gamma)
|
|
||||||
+ "_" + std::to_string(seqPar.tA) + "-"
|
|
||||||
+ qName[i];
|
|
||||||
application.createModule<MSource::SeqGamma>(seqName[i][mu], seqPar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// propagators
|
|
||||||
MFermion::GaugeProp::Par quarkPar;
|
|
||||||
quarkPar.solver = "CG_" + flavour[i];
|
|
||||||
quarkPar.source = srcName;
|
|
||||||
application.createModule<MFermion::GaugeProp>(qName[i], quarkPar);
|
|
||||||
for (unsigned int mu = 0; mu < Nd; ++mu)
|
|
||||||
{
|
|
||||||
quarkPar.source = seqName[i][mu];
|
|
||||||
seqName[i][mu] = "Q_" + flavour[i] + "-" + seqName[i][mu];
|
|
||||||
application.createModule<MFermion::GaugeProp>(seqName[i][mu], quarkPar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// contractions
|
|
||||||
MContraction::Meson::Par mesPar;
|
|
||||||
for (unsigned int i = 0; i < flavour.size(); ++i)
|
|
||||||
for (unsigned int j = i; j < flavour.size(); ++j)
|
|
||||||
{
|
|
||||||
mesPar.output = "mesons/Z2_" + flavour[i] + flavour[j];
|
|
||||||
mesPar.q1 = qName[i];
|
|
||||||
mesPar.q2 = qName[j];
|
|
||||||
mesPar.gammas = "all";
|
|
||||||
mesPar.sink = "sink";
|
|
||||||
application.createModule<MContraction::Meson>("meson_Z2_"
|
|
||||||
+ std::to_string(t)
|
|
||||||
+ "_"
|
|
||||||
+ flavour[i]
|
|
||||||
+ flavour[j],
|
|
||||||
mesPar);
|
|
||||||
}
|
|
||||||
for (unsigned int i = 0; i < flavour.size(); ++i)
|
|
||||||
for (unsigned int j = 0; j < flavour.size(); ++j)
|
|
||||||
for (unsigned int mu = 0; mu < Nd; ++mu)
|
|
||||||
{
|
|
||||||
MContraction::Meson::Par mesPar;
|
|
||||||
|
|
||||||
mesPar.output = "3pt/Z2_" + flavour[i] + flavour[j] + "_"
|
|
||||||
+ std::to_string(mu);
|
|
||||||
mesPar.q1 = qName[i];
|
|
||||||
mesPar.q2 = seqName[j][mu];
|
|
||||||
mesPar.gammas = "all";
|
|
||||||
mesPar.sink = "sink";
|
|
||||||
application.createModule<MContraction::Meson>("3pt_Z2_"
|
|
||||||
+ std::to_string(t)
|
|
||||||
+ "_"
|
|
||||||
+ flavour[i]
|
|
||||||
+ flavour[j]
|
|
||||||
+ "_"
|
|
||||||
+ std::to_string(mu),
|
|
||||||
mesPar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// execution
|
|
||||||
application.saveParameterFile("meson3pt.xml");
|
|
||||||
application.run();
|
|
||||||
|
|
||||||
// epilogue
|
|
||||||
LOG(Message) << "Grid is finalizing now" << std::endl;
|
|
||||||
Grid_finalize();
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -71,7 +71,7 @@ int main(int argc, char **argv) {
|
|||||||
std::vector<int> simd_layout = GridDefaultSimd(Nd, vComplex::Nsimd());
|
std::vector<int> simd_layout = GridDefaultSimd(Nd, vComplex::Nsimd());
|
||||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
GridCartesian Grid(latt_size, simd_layout, mpi_layout);
|
GridCartesian Grid(latt_size, simd_layout, mpi_layout);
|
||||||
GridRedBlackCartesian RBGrid(&Grid);
|
GridRedBlackCartesian RBGrid(latt_size, simd_layout, mpi_layout);
|
||||||
|
|
||||||
std::vector<int> seeds({1, 2, 3, 4, 5});
|
std::vector<int> seeds({1, 2, 3, 4, 5});
|
||||||
GridSerialRNG sRNG;
|
GridSerialRNG sRNG;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user