mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
Merge branch 'release/0.8.0'
This commit is contained in:
commit
edcf9b9293
7
.gitignore
vendored
7
.gitignore
vendored
@ -93,6 +93,7 @@ build*/*
|
|||||||
*.xcodeproj/*
|
*.xcodeproj/*
|
||||||
build.sh
|
build.sh
|
||||||
.vscode
|
.vscode
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
# Eigen source #
|
# Eigen source #
|
||||||
################
|
################
|
||||||
@ -122,4 +123,10 @@ make-bin-BUCK.sh
|
|||||||
#####################
|
#####################
|
||||||
lib/qcd/spin/gamma-gen/*.h
|
lib/qcd/spin/gamma-gen/*.h
|
||||||
lib/qcd/spin/gamma-gen/*.cc
|
lib/qcd/spin/gamma-gen/*.cc
|
||||||
|
lib/version.h
|
||||||
|
|
||||||
|
# vs code editor files #
|
||||||
|
########################
|
||||||
|
.vscode/
|
||||||
|
.vscode/settings.json
|
||||||
|
settings.json
|
||||||
|
@ -44,3 +44,4 @@ script:
|
|||||||
- make -j4
|
- make -j4
|
||||||
- ./benchmarks/Benchmark_dwf --threads 1 --debug-signals
|
- ./benchmarks/Benchmark_dwf --threads 1 --debug-signals
|
||||||
- make check
|
- make check
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@ include $(top_srcdir)/doxygen.inc
|
|||||||
|
|
||||||
bin_SCRIPTS=grid-config
|
bin_SCRIPTS=grid-config
|
||||||
|
|
||||||
|
BUILT_SOURCES = version.h
|
||||||
|
|
||||||
|
version.h:
|
||||||
|
echo "`git log -n 1 --format=format:"#define GITHASH \\"%H:%d\\"%n" HEAD`" > $(srcdir)/lib/version.h
|
||||||
|
|
||||||
.PHONY: bench check tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
.PHONY: bench check tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
|
||||||
|
|
||||||
|
@ -187,10 +187,11 @@ Alternatively, some CPU codenames can be directly used:
|
|||||||
| `<code>` | Description |
|
| `<code>` | Description |
|
||||||
| ----------- | -------------------------------------- |
|
| ----------- | -------------------------------------- |
|
||||||
| `KNL` | [Intel Xeon Phi codename Knights Landing](http://ark.intel.com/products/codename/48999/Knights-Landing) |
|
| `KNL` | [Intel Xeon Phi codename Knights Landing](http://ark.intel.com/products/codename/48999/Knights-Landing) |
|
||||||
|
| `SKL` | [Intel Skylake with AVX512 extensions](https://ark.intel.com/products/codename/37572/Skylake#@server) |
|
||||||
| `BGQ` | Blue Gene/Q |
|
| `BGQ` | Blue Gene/Q |
|
||||||
|
|
||||||
#### Notes:
|
#### Notes:
|
||||||
- We currently support AVX512 only for the Intel compiler. Support for GCC and clang will appear in future versions of Grid when the AVX512 support within GCC and clang will be more advanced.
|
- We currently support AVX512 for the Intel compiler and GCC (KNL and SKL target). Support for clang will appear in future versions of Grid when the AVX512 support in the compiler will be more advanced.
|
||||||
- For BG/Q only [bgclang](http://trac.alcf.anl.gov/projects/llvm-bgq) is supported. We do not presently plan to support more compilers for this platform.
|
- For BG/Q only [bgclang](http://trac.alcf.anl.gov/projects/llvm-bgq) is supported. We do not presently plan to support more compilers for this platform.
|
||||||
- BG/Q performances are currently rather poor. This is being investigated for future versions.
|
- BG/Q performances are currently rather poor. This is being investigated for future versions.
|
||||||
- The vector size for the `GEN` target can be specified with the `configure` script option `--enable-gen-simd-width`.
|
- The vector size for the `GEN` target can be specified with the `configure` script option `--enable-gen-simd-width`.
|
||||||
|
38
TODO
38
TODO
@ -1,21 +1,37 @@
|
|||||||
TODO:
|
TODO:
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Large item work list:
|
Code item work list
|
||||||
|
|
||||||
1)- BG/Q port and check
|
a) namespaces & indentation
|
||||||
2)- Christoph's local basis expansion Lanczos
|
GRID_BEGIN_NAMESPACE();
|
||||||
3)- Precision conversion and sort out localConvert <-- partial
|
GRID_END_NAMESPACE();
|
||||||
|
-- delete QCD namespace
|
||||||
|
|
||||||
- Consistent linear solver flop count/rate -- PARTIAL, time but no flop/s yet
|
b) GPU branch
|
||||||
4)- Physical propagator interface
|
- start branch
|
||||||
5)- Conserved currents
|
- Increase Macro use in core library support; prepare for change
|
||||||
6)- Multigrid Wilson and DWF, compare to other Multigrid implementations
|
- Audit volume of "device" code
|
||||||
7)- HDCR resume
|
- Virtual function audit
|
||||||
|
- Start port once Nvidia box is up
|
||||||
|
- Cut down volume of code for first port? How?
|
||||||
|
|
||||||
|
Physics item work list:
|
||||||
|
|
||||||
|
1)- BG/Q port and check ; Andrew says ok.
|
||||||
|
2)- Consistent linear solver flop count/rate -- PARTIAL, time but no flop/s yet
|
||||||
|
3)- Physical propagator interface
|
||||||
|
4)- Multigrid Wilson and DWF, compare to other Multigrid implementations
|
||||||
|
5)- HDCR resume
|
||||||
|
|
||||||
|
----------------------------
|
||||||
Recent DONE
|
Recent DONE
|
||||||
|
-- RNG I/O in ILDG/SciDAC (minor)
|
||||||
-- MultiRHS with spread out extra dim -- Go through filesystem with SciDAC I/O. <--- DONE
|
-- Precision conversion and sort out localConvert <-- partial/easy
|
||||||
|
-- Conserved currents (Andrew)
|
||||||
|
-- Split grid
|
||||||
|
-- Christoph's local basis expansion Lanczos
|
||||||
|
-- MultiRHS with spread out extra dim -- Go through filesystem with SciDAC I/O ; <-- DONE ; bmark cori
|
||||||
-- 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
|
||||||
|
2
VERSION
2
VERSION
@ -1,4 +1,4 @@
|
|||||||
Version : 0.7.0
|
Version : 0.8.0
|
||||||
|
|
||||||
- Clang 3.5 and above, ICPC v16 and above, GCC 6.3 and above recommended
|
- Clang 3.5 and above, ICPC v16 and above, GCC 6.3 and above recommended
|
||||||
- MPI and MPI3 comms optimisations for KNL and OPA finished
|
- MPI and MPI3 comms optimisations for KNL and OPA finished
|
||||||
|
108
benchmarks/Benchmark_IO.cc
Normal file
108
benchmarks/Benchmark_IO.cc
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include <Grid/Grid.h>
|
||||||
|
#ifdef HAVE_LIME
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Grid::QCD;
|
||||||
|
|
||||||
|
#define MSG cout << GridLogMessage
|
||||||
|
#define SEP \
|
||||||
|
"============================================================================="
|
||||||
|
#ifndef BENCH_IO_LMAX
|
||||||
|
#define BENCH_IO_LMAX 40
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef function<void(const string, LatticeFermion &)> WriterFn;
|
||||||
|
typedef function<void(LatticeFermion &, const string)> ReaderFn;
|
||||||
|
|
||||||
|
string filestem(const int l)
|
||||||
|
{
|
||||||
|
return "iobench_l" + to_string(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void limeWrite(const string filestem, LatticeFermion &vec)
|
||||||
|
{
|
||||||
|
emptyUserRecord record;
|
||||||
|
ScidacWriter binWriter(vec._grid->IsBoss());
|
||||||
|
|
||||||
|
binWriter.open(filestem + ".bin");
|
||||||
|
binWriter.writeScidacFieldRecord(vec, record);
|
||||||
|
binWriter.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void limeRead(LatticeFermion &vec, const string filestem)
|
||||||
|
{
|
||||||
|
emptyUserRecord record;
|
||||||
|
ScidacReader binReader;
|
||||||
|
|
||||||
|
binReader.open(filestem + ".bin");
|
||||||
|
binReader.readScidacFieldRecord(vec, record);
|
||||||
|
binReader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeBenchmark(const int l, const WriterFn &write)
|
||||||
|
{
|
||||||
|
auto mpi = GridDefaultMpi();
|
||||||
|
auto simd = GridDefaultSimd(Nd, vComplex::Nsimd());
|
||||||
|
vector<int> latt = {l*mpi[0], l*mpi[1], l*mpi[2], l*mpi[3]};
|
||||||
|
unique_ptr<GridCartesian> gPt(SpaceTimeGrid::makeFourDimGrid(latt, simd, mpi));
|
||||||
|
GridCartesian *g = gPt.get();
|
||||||
|
GridParallelRNG rng(g);
|
||||||
|
LatticeFermion vec(g);
|
||||||
|
emptyUserRecord record;
|
||||||
|
ScidacWriter binWriter(g->IsBoss());
|
||||||
|
|
||||||
|
cout << "-- Local volume " << l << "^4" << endl;
|
||||||
|
random(rng, vec);
|
||||||
|
write(filestem(l), vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void readBenchmark(const int l, const ReaderFn &read)
|
||||||
|
{
|
||||||
|
auto mpi = GridDefaultMpi();
|
||||||
|
auto simd = GridDefaultSimd(Nd, vComplex::Nsimd());
|
||||||
|
vector<int> latt = {l*mpi[0], l*mpi[1], l*mpi[2], l*mpi[3]};
|
||||||
|
unique_ptr<GridCartesian> gPt(SpaceTimeGrid::makeFourDimGrid(latt, simd, mpi));
|
||||||
|
GridCartesian *g = gPt.get();
|
||||||
|
LatticeFermion vec(g);
|
||||||
|
emptyUserRecord record;
|
||||||
|
ScidacReader binReader;
|
||||||
|
|
||||||
|
cout << "-- Local volume " << l << "^4" << endl;
|
||||||
|
read(vec, filestem(l));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
auto simd = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
auto mpi = GridDefaultMpi();
|
||||||
|
|
||||||
|
int64_t threads = GridThread::GetThreads();
|
||||||
|
MSG << "Grid is setup to use " << threads << " threads" << endl;
|
||||||
|
MSG << SEP << endl;
|
||||||
|
MSG << "Benchmark Lime write" << endl;
|
||||||
|
MSG << SEP << endl;
|
||||||
|
for (int l = 4; l <= BENCH_IO_LMAX; l += 2)
|
||||||
|
{
|
||||||
|
writeBenchmark(l, limeWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG << "Benchmark Lime read" << endl;
|
||||||
|
MSG << SEP << endl;
|
||||||
|
for (int l = 4; l <= BENCH_IO_LMAX; l += 2)
|
||||||
|
{
|
||||||
|
readBenchmark(l, limeRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
@ -106,7 +106,7 @@ int main (int argc, char ** argv)
|
|||||||
for(int i=0;i<Nloop;i++){
|
for(int i=0;i<Nloop;i++){
|
||||||
double start=usecond();
|
double start=usecond();
|
||||||
|
|
||||||
std::vector<CartesianCommunicator::CommsRequest_t> requests;
|
std::vector<CommsRequest_t> requests;
|
||||||
|
|
||||||
ncomm=0;
|
ncomm=0;
|
||||||
for(int mu=0;mu<4;mu++){
|
for(int mu=0;mu<4;mu++){
|
||||||
@ -202,7 +202,7 @@ int main (int argc, char ** argv)
|
|||||||
int recv_from_rank;
|
int recv_from_rank;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<CartesianCommunicator::CommsRequest_t> requests;
|
std::vector<CommsRequest_t> requests;
|
||||||
Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
|
Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
|
||||||
Grid.SendToRecvFromBegin(requests,
|
Grid.SendToRecvFromBegin(requests,
|
||||||
(void *)&xbuf[mu][0],
|
(void *)&xbuf[mu][0],
|
||||||
@ -215,7 +215,7 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
comm_proc = mpi_layout[mu]-1;
|
comm_proc = mpi_layout[mu]-1;
|
||||||
{
|
{
|
||||||
std::vector<CartesianCommunicator::CommsRequest_t> requests;
|
std::vector<CommsRequest_t> requests;
|
||||||
Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
|
Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
|
||||||
Grid.SendToRecvFromBegin(requests,
|
Grid.SendToRecvFromBegin(requests,
|
||||||
(void *)&xbuf[mu+4][0],
|
(void *)&xbuf[mu+4][0],
|
||||||
@ -290,7 +290,7 @@ int main (int argc, char ** argv)
|
|||||||
dbytes=0;
|
dbytes=0;
|
||||||
ncomm=0;
|
ncomm=0;
|
||||||
|
|
||||||
std::vector<CartesianCommunicator::CommsRequest_t> requests;
|
std::vector<CommsRequest_t> requests;
|
||||||
|
|
||||||
for(int mu=0;mu<4;mu++){
|
for(int mu=0;mu<4;mu++){
|
||||||
|
|
||||||
@ -383,7 +383,7 @@ int main (int argc, char ** argv)
|
|||||||
for(int i=0;i<Nloop;i++){
|
for(int i=0;i<Nloop;i++){
|
||||||
double start=usecond();
|
double start=usecond();
|
||||||
|
|
||||||
std::vector<CartesianCommunicator::CommsRequest_t> requests;
|
std::vector<CommsRequest_t> requests;
|
||||||
dbytes=0;
|
dbytes=0;
|
||||||
ncomm=0;
|
ncomm=0;
|
||||||
for(int mu=0;mu<4;mu++){
|
for(int mu=0;mu<4;mu++){
|
||||||
@ -481,7 +481,7 @@ int main (int argc, char ** argv)
|
|||||||
for(int i=0;i<Nloop;i++){
|
for(int i=0;i<Nloop;i++){
|
||||||
double start=usecond();
|
double start=usecond();
|
||||||
|
|
||||||
std::vector<CartesianCommunicator::CommsRequest_t> requests;
|
std::vector<CommsRequest_t> requests;
|
||||||
dbytes=0;
|
dbytes=0;
|
||||||
ncomm=0;
|
ncomm=0;
|
||||||
|
|
||||||
|
@ -48,10 +48,19 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
|
||||||
|
|
||||||
std::vector<int> latt4 = GridDefaultLatt();
|
std::vector<int> latt4 = GridDefaultLatt();
|
||||||
const int Ls=16;
|
int Ls=16;
|
||||||
|
for(int i=0;i<argc;i++)
|
||||||
|
if(std::string(argv[i]) == "-Ls"){
|
||||||
|
std::stringstream ss(argv[i+1]); ss >> Ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLogLayout();
|
||||||
|
|
||||||
|
long unsigned int single_site_flops = 8*QCD::Nc*(7+16*QCD::Nc);
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
@ -181,7 +190,7 @@ int main (int argc, char ** argv)
|
|||||||
FGrid->Barrier();
|
FGrid->Barrier();
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=1344*volume*ncall;
|
double flops=single_site_flops*volume*ncall;
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
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 result "<< norm2(result)<<std::endl;
|
||||||
@ -220,7 +229,7 @@ int main (int argc, char ** argv)
|
|||||||
FGrid->Barrier();
|
FGrid->Barrier();
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=1344*volume*ncall;
|
double flops=single_site_flops*volume*ncall;
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called half prec comms Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
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 = "<< flops/(t1-t0)<<std::endl;
|
||||||
@ -271,7 +280,7 @@ int main (int argc, char ** argv)
|
|||||||
double t1=usecond();
|
double t1=usecond();
|
||||||
FGrid->Barrier();
|
FGrid->Barrier();
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=1344*volume*ncall;
|
double flops=single_site_flops*volume*ncall;
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called Dw s_inner "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
std::cout<<GridLogMessage << "Called Dw s_inner "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
|
||||||
std::cout<<GridLogMessage << "mflop/s = "<< flops/(t1-t0)<<std::endl;
|
std::cout<<GridLogMessage << "mflop/s = "<< flops/(t1-t0)<<std::endl;
|
||||||
@ -349,7 +358,7 @@ int main (int argc, char ** argv)
|
|||||||
// sDw.stat.print();
|
// sDw.stat.print();
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=(1344.0*volume*ncall)/2;
|
double flops=(single_site_flops*volume*ncall)/2.0;
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "sDeo mflop/s = "<< flops/(t1-t0)<<std::endl;
|
std::cout<<GridLogMessage << "sDeo mflop/s = "<< flops/(t1-t0)<<std::endl;
|
||||||
std::cout<<GridLogMessage << "sDeo mflop/s per rank "<< flops/(t1-t0)/NP<<std::endl;
|
std::cout<<GridLogMessage << "sDeo mflop/s per rank "<< flops/(t1-t0)/NP<<std::endl;
|
||||||
@ -472,7 +481,7 @@ int main (int argc, char ** argv)
|
|||||||
FGrid->Barrier();
|
FGrid->Barrier();
|
||||||
|
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=(1344.0*volume*ncall)/2;
|
double flops=(single_site_flops*volume*ncall)/2.0;
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Deo mflop/s = "<< flops/(t1-t0)<<std::endl;
|
std::cout<<GridLogMessage << "Deo mflop/s = "<< flops/(t1-t0)<<std::endl;
|
||||||
std::cout<<GridLogMessage << "Deo mflop/s per rank "<< flops/(t1-t0)/NP<<std::endl;
|
std::cout<<GridLogMessage << "Deo mflop/s per rank "<< flops/(t1-t0)/NP<<std::endl;
|
||||||
|
@ -51,6 +51,7 @@ int main (int argc, char ** argv)
|
|||||||
{
|
{
|
||||||
Grid_init(&argc,&argv);
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||||
std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<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;
|
||||||
@ -107,6 +108,7 @@ void benchDw(std::vector<int> & latt4, int Ls, int threads,int report )
|
|||||||
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
||||||
|
long unsigned int single_site_flops = 8*QCD::Nc*(7+16*QCD::Nc);
|
||||||
|
|
||||||
std::vector<int> seeds4({1,2,3,4});
|
std::vector<int> seeds4({1,2,3,4});
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
std::vector<int> seeds5({5,6,7,8});
|
||||||
@ -196,7 +198,7 @@ void benchDw(std::vector<int> & latt4, int Ls, int threads,int report )
|
|||||||
|
|
||||||
if ( ! report ) {
|
if ( ! report ) {
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=1344*volume*ncall;
|
double flops=single_site_flops*volume*ncall;
|
||||||
std::cout <<"\t"<<NP<< "\t"<<flops/(t1-t0)<< "\t";
|
std::cout <<"\t"<<NP<< "\t"<<flops/(t1-t0)<< "\t";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +230,7 @@ void benchDw(std::vector<int> & latt4, int Ls, int threads,int report )
|
|||||||
|
|
||||||
if(!report){
|
if(!report){
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=(1344.0*volume*ncall)/2;
|
double flops=(single_site_flops*volume*ncall)/2.0;
|
||||||
std::cout<< flops/(t1-t0);
|
std::cout<< flops/(t1-t0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,6 +239,7 @@ void benchDw(std::vector<int> & latt4, int Ls, int threads,int report )
|
|||||||
#define CHECK_SDW
|
#define CHECK_SDW
|
||||||
void benchsDw(std::vector<int> & latt4, int Ls, int threads, int report )
|
void benchsDw(std::vector<int> & latt4, int Ls, int threads, int report )
|
||||||
{
|
{
|
||||||
|
long unsigned int single_site_flops = 8*QCD::Nc*(7+16*QCD::Nc);
|
||||||
|
|
||||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(latt4, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(latt4, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||||
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||||
@ -321,7 +324,7 @@ void benchsDw(std::vector<int> & latt4, int Ls, int threads, int report )
|
|||||||
Counter.Report();
|
Counter.Report();
|
||||||
} else {
|
} else {
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=1344*volume*ncall;
|
double flops=single_site_flops*volume*ncall;
|
||||||
std::cout<<"\t"<< flops/(t1-t0);
|
std::cout<<"\t"<< flops/(t1-t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +361,7 @@ void benchsDw(std::vector<int> & latt4, int Ls, int threads, int report )
|
|||||||
CounterSdw.Report();
|
CounterSdw.Report();
|
||||||
} else {
|
} else {
|
||||||
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
double volume=Ls; for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
|
||||||
double flops=(1344.0*volume*ncall)/2;
|
double flops=(single_site_flops*volume*ncall)/2.0;
|
||||||
std::cout<<"\t"<< flops/(t1-t0);
|
std::cout<<"\t"<< flops/(t1-t0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
190
benchmarks/Benchmark_gparity.cc
Normal file
190
benchmarks/Benchmark_gparity.cc
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#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*1320*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*1320*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*1320*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();
|
||||||
|
}
|
||||||
|
|
@ -55,7 +55,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||||
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s"<<"\t\t"<<"Gflop/s"<<"\t\t seconds"<<std::endl;
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s"<<"\t\t"<<"Gflop/s"<<"\t\t seconds"<<std::endl;
|
||||||
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
uint64_t lmax=96;
|
uint64_t lmax=64;
|
||||||
#define NLOOP (10*lmax*lmax*lmax*lmax/vol)
|
#define NLOOP (10*lmax*lmax*lmax*lmax/vol)
|
||||||
for(int lat=8;lat<=lmax;lat+=8){
|
for(int lat=8;lat<=lmax;lat+=8){
|
||||||
|
|
||||||
|
@ -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(latt_size,simd_layout,mpi_layout);
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
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;
|
||||||
|
@ -35,9 +35,11 @@ using namespace Grid::QCD;
|
|||||||
int main (int argc, char ** argv)
|
int main (int argc, char ** argv)
|
||||||
{
|
{
|
||||||
Grid_init(&argc,&argv);
|
Grid_init(&argc,&argv);
|
||||||
#define LMAX (64)
|
#define LMAX (32)
|
||||||
|
#define LMIN (16)
|
||||||
|
#define LINC (4)
|
||||||
|
|
||||||
int64_t Nloop=20;
|
int64_t Nloop=2000;
|
||||||
|
|
||||||
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();
|
||||||
@ -51,7 +53,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
||||||
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
|
|
||||||
for(int lat=2;lat<=LMAX;lat+=2){
|
for(int lat=LMIN;lat<=LMAX;lat+=LINC){
|
||||||
|
|
||||||
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
||||||
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
@ -83,7 +85,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
||||||
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
|
|
||||||
for(int lat=2;lat<=LMAX;lat+=2){
|
for(int lat=LMIN;lat<=LMAX;lat+=LINC){
|
||||||
|
|
||||||
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
||||||
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
@ -114,7 +116,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
||||||
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
|
|
||||||
for(int lat=2;lat<=LMAX;lat+=2){
|
for(int lat=LMIN;lat<=LMAX;lat+=LINC){
|
||||||
|
|
||||||
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
||||||
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
@ -145,7 +147,38 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
||||||
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
|
|
||||||
for(int lat=2;lat<=LMAX;lat+=2){
|
for(int lat=LMIN;lat<=LMAX;lat+=LINC){
|
||||||
|
|
||||||
|
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
||||||
|
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
|
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
||||||
|
|
||||||
|
LatticeColourMatrix z(&Grid); random(pRNG,z);
|
||||||
|
LatticeColourMatrix x(&Grid); random(pRNG,x);
|
||||||
|
LatticeColourMatrix y(&Grid); random(pRNG,y);
|
||||||
|
|
||||||
|
double start=usecond();
|
||||||
|
for(int64_t i=0;i<Nloop;i++){
|
||||||
|
mac(z,x,y);
|
||||||
|
}
|
||||||
|
double stop=usecond();
|
||||||
|
double time = (stop-start)/Nloop*1000.0;
|
||||||
|
|
||||||
|
double bytes=3*vol*Nc*Nc*sizeof(Complex);
|
||||||
|
double flops=Nc*Nc*(6+8+8)*vol;
|
||||||
|
std::cout<<GridLogMessage<<std::setprecision(3) << lat<<"\t\t"<<bytes<<" \t\t"<<bytes/time<<"\t\t" << flops/time<<std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "= Benchmarking SU3xSU3 CovShiftForward(z,x,y)"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
|
|
||||||
|
for(int lat=LMIN;lat<=LMAX;lat+=LINC){
|
||||||
|
|
||||||
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
||||||
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
@ -157,18 +190,64 @@ int main (int argc, char ** argv)
|
|||||||
LatticeColourMatrix x(&Grid); random(pRNG,x);
|
LatticeColourMatrix x(&Grid); random(pRNG,x);
|
||||||
LatticeColourMatrix y(&Grid); random(pRNG,y);
|
LatticeColourMatrix y(&Grid); random(pRNG,y);
|
||||||
|
|
||||||
double start=usecond();
|
for(int mu=0;mu<4;mu++){
|
||||||
for(int64_t i=0;i<Nloop;i++){
|
double start=usecond();
|
||||||
mac(z,x,y);
|
for(int64_t i=0;i<Nloop;i++){
|
||||||
|
z = PeriodicBC::CovShiftForward(x,mu,y);
|
||||||
|
}
|
||||||
|
double stop=usecond();
|
||||||
|
double time = (stop-start)/Nloop*1000.0;
|
||||||
|
|
||||||
|
|
||||||
|
double bytes=3*vol*Nc*Nc*sizeof(Complex);
|
||||||
|
double flops=Nc*Nc*(6+8+8)*vol;
|
||||||
|
std::cout<<GridLogMessage<<std::setprecision(3) << lat<<"\t\t"<<bytes<<" \t\t"<<bytes/time<<"\t\t" << flops/time<<std::endl;
|
||||||
}
|
}
|
||||||
double stop=usecond();
|
}
|
||||||
double time = (stop-start)/Nloop*1000.0;
|
#if 1
|
||||||
|
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "= Benchmarking SU3xSU3 z= x * Cshift(y)"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << " L "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
|
||||||
|
|
||||||
double bytes=3*vol*Nc*Nc*sizeof(Complex);
|
for(int lat=LMIN;lat<=LMAX;lat+=LINC){
|
||||||
double flops=Nc*Nc*(8+8+8)*vol;
|
std::vector<int> latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
|
||||||
std::cout<<GridLogMessage<<std::setprecision(3) << lat<<"\t\t"<<bytes<<" \t\t"<<bytes/time<<"\t\t" << flops/time<<std::endl;
|
int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||||
|
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
||||||
|
|
||||||
|
LatticeColourMatrix z(&Grid); random(pRNG,z);
|
||||||
|
LatticeColourMatrix x(&Grid); random(pRNG,x);
|
||||||
|
LatticeColourMatrix y(&Grid); random(pRNG,y);
|
||||||
|
LatticeColourMatrix tmp(&Grid);
|
||||||
|
|
||||||
|
for(int mu=0;mu<4;mu++){
|
||||||
|
double tshift=0;
|
||||||
|
double tmult =0;
|
||||||
|
|
||||||
|
double start=usecond();
|
||||||
|
for(int64_t i=0;i<Nloop;i++){
|
||||||
|
tshift-=usecond();
|
||||||
|
tmp = Cshift(y,mu,-1);
|
||||||
|
tshift+=usecond();
|
||||||
|
tmult-=usecond();
|
||||||
|
z = x*tmp;
|
||||||
|
tmult+=usecond();
|
||||||
|
}
|
||||||
|
double stop=usecond();
|
||||||
|
double time = (stop-start)/Nloop;
|
||||||
|
tshift = tshift/Nloop;
|
||||||
|
tmult = tmult /Nloop;
|
||||||
|
|
||||||
|
double bytes=3*vol*Nc*Nc*sizeof(Complex);
|
||||||
|
double flops=Nc*Nc*(6+8+8)*vol;
|
||||||
|
std::cout<<GridLogMessage<<std::setprecision(3) << "total us "<<time<<" shift "<<tshift <<" mult "<<tmult<<std::endl;
|
||||||
|
time = time * 1000; // convert to NS for GB/s
|
||||||
|
std::cout<<GridLogMessage<<std::setprecision(3) << lat<<"\t\t"<<bytes<<" \t\t"<<bytes/time<<"\t\t" << flops/time<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Grid_finalize();
|
Grid_finalize();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Source file: ./benchmarks/Benchmark_wilson.cc
|
Source file: ./benchmarks/Benchmark_wilson.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2018
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||||
@ -32,6 +32,9 @@ using namespace std;
|
|||||||
using namespace Grid;
|
using namespace Grid;
|
||||||
using namespace Grid::QCD;
|
using namespace Grid::QCD;
|
||||||
|
|
||||||
|
|
||||||
|
#include "Grid/util/Profiling.h"
|
||||||
|
|
||||||
template<class d>
|
template<class d>
|
||||||
struct scal {
|
struct scal {
|
||||||
d internal;
|
d internal;
|
||||||
@ -45,6 +48,7 @@ struct scal {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool overlapComms = false;
|
bool overlapComms = false;
|
||||||
|
bool perfProfiling = false;
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
int main (int argc, char ** argv)
|
||||||
{
|
{
|
||||||
@ -53,18 +57,29 @@ int main (int argc, char ** argv)
|
|||||||
if( GridCmdOptionExists(argv,argv+argc,"--asynch") ){
|
if( GridCmdOptionExists(argv,argv+argc,"--asynch") ){
|
||||||
overlapComms = true;
|
overlapComms = true;
|
||||||
}
|
}
|
||||||
|
if( GridCmdOptionExists(argv,argv+argc,"--perf") ){
|
||||||
|
perfProfiling = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
long unsigned int single_site_flops = 8*QCD::Nc*(7+16*QCD::Nc);
|
||||||
|
|
||||||
|
|
||||||
std::vector<int> latt_size = GridDefaultLatt();
|
std::vector<int> latt_size = GridDefaultLatt();
|
||||||
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(latt_size,simd_layout,mpi_layout);
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
|
||||||
|
GridLogLayout();
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Grid floating point word size is REALF"<< sizeof(RealF)<<std::endl;
|
std::cout<<GridLogMessage << "Grid floating point word size is REALF"<< sizeof(RealF)<<std::endl;
|
||||||
std::cout<<GridLogMessage << "Grid floating point word size is REALD"<< sizeof(RealD)<<std::endl;
|
std::cout<<GridLogMessage << "Grid floating point word size is REALD"<< sizeof(RealD)<<std::endl;
|
||||||
std::cout<<GridLogMessage << "Grid floating point word size is REAL"<< sizeof(Real)<<std::endl;
|
std::cout<<GridLogMessage << "Grid floating point word size is REAL"<< sizeof(Real)<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "Grid number of colours : "<< QCD::Nc <<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "Benchmarking Wilson operator in the fundamental representation" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
std::vector<int> seeds({1,2,3,4});
|
std::vector<int> seeds({1,2,3,4});
|
||||||
GridParallelRNG pRNG(&Grid);
|
GridParallelRNG pRNG(&Grid);
|
||||||
@ -134,9 +149,25 @@ int main (int argc, char ** argv)
|
|||||||
Dw.Dhop(src,result,0);
|
Dw.Dhop(src,result,0);
|
||||||
}
|
}
|
||||||
double t1=usecond();
|
double t1=usecond();
|
||||||
double flops=1344*volume*ncall;
|
double flops=single_site_flops*volume*ncall;
|
||||||
|
|
||||||
|
if (perfProfiling){
|
||||||
|
std::cout<<GridLogMessage << "Profiling Dw with perf"<<std::endl;
|
||||||
|
|
||||||
|
System::profile("kernel", [&]() {
|
||||||
|
for(int i=0;i<ncall;i++){
|
||||||
|
Dw.Dhop(src,result,0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage << "Generated kernel.data"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "Use with: perf report -i kernel.data"<<std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Called Dw"<<std::endl;
|
std::cout<<GridLogMessage << "Called Dw"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage << "flops per site " << single_site_flops << std::endl;
|
||||||
std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
|
std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
|
||||||
std::cout<<GridLogMessage << "norm ref "<< norm2(ref)<<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 = "<< flops/(t1-t0)<<std::endl;
|
||||||
|
@ -62,6 +62,7 @@ int main (int argc, char ** argv)
|
|||||||
std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<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<< "*****************************************************************" <<std::endl;
|
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||||
|
std::cout << GridLogMessage<< "* Number of colours "<< QCD::Nc <<std::endl;
|
||||||
std::cout << GridLogMessage<< "* Benchmarking WilsonFermionR::Dhop "<<std::endl;
|
std::cout << GridLogMessage<< "* Benchmarking WilsonFermionR::Dhop "<<std::endl;
|
||||||
std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplex::Nsimd()<<std::endl;
|
std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplex::Nsimd()<<std::endl;
|
||||||
if ( sizeof(Real)==4 ) std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
|
if ( sizeof(Real)==4 ) std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
|
||||||
@ -69,13 +70,15 @@ int main (int argc, char ** argv)
|
|||||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
|
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::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;
|
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3 WilsonKernels" <<std::endl;
|
||||||
|
std::cout << GridLogMessage << "* OpenMP threads : "<< GridThread::GetThreads() <<std::endl;
|
||||||
|
std::cout << GridLogMessage << "* MPI tasks : "<< GridCmdVectorIntToString(mpi_layout) << std::endl;
|
||||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "============================================================================="<< std::endl;
|
std::cout<<GridLogMessage << "================================================================================================="<< std::endl;
|
||||||
std::cout<<GridLogMessage << "= Benchmarking Wilson" << std::endl;
|
std::cout<<GridLogMessage << "= Benchmarking Wilson operator in the fundamental representation" << std::endl;
|
||||||
std::cout<<GridLogMessage << "============================================================================="<< std::endl;
|
std::cout<<GridLogMessage << "================================================================================================="<< std::endl;
|
||||||
std::cout<<GridLogMessage << "Volume\t\t\tWilson/MFLOPs\tWilsonDag/MFLOPs" << std::endl;
|
std::cout<<GridLogMessage << "Volume\t\t\tWilson/MFLOPs\tWilsonDag/MFLOPs\tWilsonEO/MFLOPs\tWilsonDagEO/MFLOPs" << std::endl;
|
||||||
std::cout<<GridLogMessage << "============================================================================="<< std::endl;
|
std::cout<<GridLogMessage << "================================================================================================="<< std::endl;
|
||||||
|
|
||||||
int Lmax = 32;
|
int Lmax = 32;
|
||||||
int dmin = 0;
|
int dmin = 0;
|
||||||
@ -93,17 +96,24 @@ 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(latt_size,simd_layout,mpi_layout);
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
LatticeGaugeField Umu(&Grid); random(pRNG,Umu);
|
LatticeGaugeField Umu(&Grid); random(pRNG,Umu);
|
||||||
LatticeFermion src(&Grid); random(pRNG,src);
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
LatticeFermion result(&Grid); result=zero;
|
LatticeFermion src_o(&RBGrid); pickCheckerboard(Odd,src_o,src);
|
||||||
|
LatticeFermion result(&Grid); result=zero;
|
||||||
|
LatticeFermion result_e(&RBGrid); result_e=zero;
|
||||||
|
|
||||||
double volume = std::accumulate(latt_size.begin(),latt_size.end(),1,std::multiplies<int>());
|
double volume = std::accumulate(latt_size.begin(),latt_size.end(),1,std::multiplies<int>());
|
||||||
|
|
||||||
WilsonFermionR Dw(Umu,Grid,RBGrid,mass,params);
|
WilsonFermionR Dw(Umu,Grid,RBGrid,mass,params);
|
||||||
|
|
||||||
|
// Full operator
|
||||||
|
bench_wilson(src,result,Dw,volume,DaggerNo);
|
||||||
|
bench_wilson(src,result,Dw,volume,DaggerYes);
|
||||||
|
std::cout << "\t";
|
||||||
|
// EO
|
||||||
bench_wilson(src,result,Dw,volume,DaggerNo);
|
bench_wilson(src,result,Dw,volume,DaggerNo);
|
||||||
bench_wilson(src,result,Dw,volume,DaggerYes);
|
bench_wilson(src,result,Dw,volume,DaggerYes);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
@ -122,9 +132,26 @@ void bench_wilson (
|
|||||||
int const dag )
|
int const dag )
|
||||||
{
|
{
|
||||||
int ncall = 1000;
|
int ncall = 1000;
|
||||||
|
long unsigned int single_site_flops = 8*QCD::Nc*(7+16*QCD::Nc);
|
||||||
double t0 = usecond();
|
double t0 = usecond();
|
||||||
for(int i=0; i<ncall; i++) { Dw.Dhop(src,result,dag); }
|
for(int i=0; i<ncall; i++) { Dw.Dhop(src,result,dag); }
|
||||||
double t1 = usecond();
|
double t1 = usecond();
|
||||||
double flops = 1344 * volume * ncall;
|
double flops = single_site_flops * volume * ncall;
|
||||||
|
std::cout << flops/(t1-t0) << "\t\t";
|
||||||
|
}
|
||||||
|
|
||||||
|
void bench_wilson_eo (
|
||||||
|
LatticeFermion & src,
|
||||||
|
LatticeFermion & result,
|
||||||
|
WilsonFermionR & Dw,
|
||||||
|
double const volume,
|
||||||
|
int const dag )
|
||||||
|
{
|
||||||
|
int ncall = 1000;
|
||||||
|
long unsigned int single_site_flops = 8*QCD::Nc*(7+16*QCD::Nc);
|
||||||
|
double t0 = usecond();
|
||||||
|
for(int i=0; i<ncall; i++) { Dw.DhopEO(src,result,dag); }
|
||||||
|
double t1 = usecond();
|
||||||
|
double flops = (single_site_flops * volume * ncall)/2.0;
|
||||||
std::cout << flops/(t1-t0) << "\t\t";
|
std::cout << flops/(t1-t0) << "\t\t";
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.3.3.tar.bz2'
|
EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.3.3.tar.bz2'
|
||||||
|
|
||||||
echo "-- deploying Eigen source..."
|
echo "-- deploying Eigen source..."
|
||||||
wget ${EIGEN_URL} --no-check-certificate
|
wget ${EIGEN_URL} --no-check-certificate && ./scripts/update_eigen.sh `basename ${EIGEN_URL}` && rm `basename ${EIGEN_URL}`
|
||||||
./scripts/update_eigen.sh `basename ${EIGEN_URL}`
|
|
||||||
rm `basename ${EIGEN_URL}`
|
|
||||||
|
|
||||||
echo '-- generating Make.inc files...'
|
echo '-- generating Make.inc files...'
|
||||||
./scripts/filelist
|
./scripts/filelist
|
||||||
|
30
configure.ac
30
configure.ac
@ -249,6 +249,9 @@ case ${ax_cv_cxx_compiler_vendor} in
|
|||||||
AVX512)
|
AVX512)
|
||||||
AC_DEFINE([AVX512],[1],[AVX512 intrinsics])
|
AC_DEFINE([AVX512],[1],[AVX512 intrinsics])
|
||||||
SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';;
|
SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';;
|
||||||
|
SKL)
|
||||||
|
AC_DEFINE([AVX512],[1],[AVX512 intrinsics for SkyLake Xeon])
|
||||||
|
SIMD_FLAGS='-march=skylake-avx512';;
|
||||||
KNC)
|
KNC)
|
||||||
AC_DEFINE([IMCI],[1],[IMCI intrinsics for Knights Corner])
|
AC_DEFINE([IMCI],[1],[IMCI intrinsics for Knights Corner])
|
||||||
SIMD_FLAGS='';;
|
SIMD_FLAGS='';;
|
||||||
@ -337,19 +340,19 @@ case ${ac_PRECISION} in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
###################### Shared memory allocation technique under MPI3
|
###################### Shared memory allocation technique under MPI3
|
||||||
AC_ARG_ENABLE([shm],[AC_HELP_STRING([--enable-shm=shmget|shmopen|hugetlbfs],
|
AC_ARG_ENABLE([shm],[AC_HELP_STRING([--enable-shm=shmopen|hugetlbfs|shmnone],
|
||||||
[Select SHM allocation technique])],[ac_SHM=${enable_shm}],[ac_SHM=shmopen])
|
[Select SHM allocation technique])],[ac_SHM=${enable_shm}],[ac_SHM=shmopen])
|
||||||
|
|
||||||
case ${ac_SHM} in
|
case ${ac_SHM} in
|
||||||
|
|
||||||
shmget)
|
|
||||||
AC_DEFINE([GRID_MPI3_SHMGET],[1],[GRID_MPI3_SHMGET] )
|
|
||||||
;;
|
|
||||||
|
|
||||||
shmopen)
|
shmopen)
|
||||||
AC_DEFINE([GRID_MPI3_SHMOPEN],[1],[GRID_MPI3_SHMOPEN] )
|
AC_DEFINE([GRID_MPI3_SHMOPEN],[1],[GRID_MPI3_SHMOPEN] )
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
shmnone)
|
||||||
|
AC_DEFINE([GRID_MPI3_SHM_NONE],[1],[GRID_MPI3_SHM_NONE] )
|
||||||
|
;;
|
||||||
|
|
||||||
hugetlbfs)
|
hugetlbfs)
|
||||||
AC_DEFINE([GRID_MPI3_SHMMMAP],[1],[GRID_MPI3_SHMMMAP] )
|
AC_DEFINE([GRID_MPI3_SHMMMAP],[1],[GRID_MPI3_SHMMMAP] )
|
||||||
;;
|
;;
|
||||||
@ -367,7 +370,7 @@ AC_ARG_ENABLE([shmpath],[AC_HELP_STRING([--enable-shmpath=path],
|
|||||||
AC_DEFINE_UNQUOTED([GRID_SHM_PATH],["$ac_SHMPATH"],[Path to a hugetlbfs filesystem for MMAPing])
|
AC_DEFINE_UNQUOTED([GRID_SHM_PATH],["$ac_SHMPATH"],[Path to a hugetlbfs filesystem for MMAPing])
|
||||||
|
|
||||||
############### communication type selection
|
############### communication type selection
|
||||||
AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi|mpi-auto|mpi3|mpi3-auto|shmem],
|
AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi|mpi-auto],
|
||||||
[Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none])
|
[Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none])
|
||||||
|
|
||||||
case ${ac_COMMS} in
|
case ${ac_COMMS} in
|
||||||
@ -375,22 +378,10 @@ case ${ac_COMMS} in
|
|||||||
AC_DEFINE([GRID_COMMS_NONE],[1],[GRID_COMMS_NONE] )
|
AC_DEFINE([GRID_COMMS_NONE],[1],[GRID_COMMS_NONE] )
|
||||||
comms_type='none'
|
comms_type='none'
|
||||||
;;
|
;;
|
||||||
mpi3*)
|
mpi*)
|
||||||
AC_DEFINE([GRID_COMMS_MPI3],[1],[GRID_COMMS_MPI3] )
|
AC_DEFINE([GRID_COMMS_MPI3],[1],[GRID_COMMS_MPI3] )
|
||||||
comms_type='mpi3'
|
comms_type='mpi3'
|
||||||
;;
|
;;
|
||||||
mpit)
|
|
||||||
AC_DEFINE([GRID_COMMS_MPIT],[1],[GRID_COMMS_MPIT] )
|
|
||||||
comms_type='mpit'
|
|
||||||
;;
|
|
||||||
mpi*)
|
|
||||||
AC_DEFINE([GRID_COMMS_MPI],[1],[GRID_COMMS_MPI] )
|
|
||||||
comms_type='mpi'
|
|
||||||
;;
|
|
||||||
shmem)
|
|
||||||
AC_DEFINE([GRID_COMMS_SHMEM],[1],[GRID_COMMS_SHMEM] )
|
|
||||||
comms_type='shmem'
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
AC_MSG_ERROR([${ac_COMMS} unsupported --enable-comms option]);
|
AC_MSG_ERROR([${ac_COMMS} unsupported --enable-comms option]);
|
||||||
;;
|
;;
|
||||||
@ -550,6 +541,7 @@ AC_CONFIG_FILES(tests/forces/Makefile)
|
|||||||
AC_CONFIG_FILES(tests/hadrons/Makefile)
|
AC_CONFIG_FILES(tests/hadrons/Makefile)
|
||||||
AC_CONFIG_FILES(tests/hmc/Makefile)
|
AC_CONFIG_FILES(tests/hmc/Makefile)
|
||||||
AC_CONFIG_FILES(tests/solver/Makefile)
|
AC_CONFIG_FILES(tests/solver/Makefile)
|
||||||
|
AC_CONFIG_FILES(tests/lanczos/Makefile)
|
||||||
AC_CONFIG_FILES(tests/smearing/Makefile)
|
AC_CONFIG_FILES(tests/smearing/Makefile)
|
||||||
AC_CONFIG_FILES(tests/qdpxx/Makefile)
|
AC_CONFIG_FILES(tests/qdpxx/Makefile)
|
||||||
AC_CONFIG_FILES(tests/testu01/Makefile)
|
AC_CONFIG_FILES(tests/testu01/Makefile)
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Application.cc
|
Source file: extras/Hadrons/Application.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -43,12 +42,7 @@ using namespace Hadrons;
|
|||||||
// constructors ////////////////////////////////////////////////////////////////
|
// constructors ////////////////////////////////////////////////////////////////
|
||||||
Application::Application(void)
|
Application::Application(void)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Modules available:" << std::endl;
|
initLogger();
|
||||||
auto list = ModuleFactory::getInstance().getBuilderList();
|
|
||||||
for (auto &m: list)
|
|
||||||
{
|
|
||||||
LOG(Message) << " " << m << std::endl;
|
|
||||||
}
|
|
||||||
auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim);
|
auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim);
|
||||||
locVol_ = 1;
|
locVol_ = 1;
|
||||||
for (unsigned int d = 0; d < dim.size(); ++d)
|
for (unsigned int d = 0; d < dim.size(); ++d)
|
||||||
@ -73,12 +67,6 @@ Application::Application(const std::string parameterFileName)
|
|||||||
parameterFileName_ = parameterFileName;
|
parameterFileName_ = parameterFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
// environment shortcut ////////////////////////////////////////////////////////
|
|
||||||
Environment & Application::env(void) const
|
|
||||||
{
|
|
||||||
return Environment::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
// access //////////////////////////////////////////////////////////////////////
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
void Application::setPar(const Application::GlobalPar &par)
|
void Application::setPar(const Application::GlobalPar &par)
|
||||||
{
|
{
|
||||||
@ -94,14 +82,13 @@ const Application::GlobalPar & Application::getPar(void)
|
|||||||
// execute /////////////////////////////////////////////////////////////////////
|
// execute /////////////////////////////////////////////////////////////////////
|
||||||
void Application::run(void)
|
void Application::run(void)
|
||||||
{
|
{
|
||||||
if (!parameterFileName_.empty() and (env().getNModule() == 0))
|
if (!parameterFileName_.empty() and (vm().getNModule() == 0))
|
||||||
{
|
{
|
||||||
parseParameterFile(parameterFileName_);
|
parseParameterFile(parameterFileName_);
|
||||||
}
|
}
|
||||||
if (!scheduled_)
|
vm().printContent();
|
||||||
{
|
env().printContent();
|
||||||
schedule();
|
schedule();
|
||||||
}
|
|
||||||
printSchedule();
|
printSchedule();
|
||||||
configLoop();
|
configLoop();
|
||||||
}
|
}
|
||||||
@ -124,12 +111,20 @@ void Application::parseParameterFile(const std::string parameterFileName)
|
|||||||
LOG(Message) << "Building application from '" << parameterFileName << "'..." << std::endl;
|
LOG(Message) << "Building application from '" << parameterFileName << "'..." << std::endl;
|
||||||
read(reader, "parameters", par);
|
read(reader, "parameters", par);
|
||||||
setPar(par);
|
setPar(par);
|
||||||
push(reader, "modules");
|
if (!push(reader, "modules"))
|
||||||
push(reader, "module");
|
{
|
||||||
|
HADRON_ERROR(Parsing, "Cannot open node 'modules' in parameter file '"
|
||||||
|
+ parameterFileName + "'");
|
||||||
|
}
|
||||||
|
if (!push(reader, "module"))
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Parsing, "Cannot open node 'modules/module' in parameter file '"
|
||||||
|
+ parameterFileName + "'");
|
||||||
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
read(reader, "id", id);
|
read(reader, "id", id);
|
||||||
env().createModule(id.name, id.type, reader);
|
vm().createModule(id.name, id.type, reader);
|
||||||
} while (reader.nextElement("module"));
|
} while (reader.nextElement("module"));
|
||||||
pop(reader);
|
pop(reader);
|
||||||
pop(reader);
|
pop(reader);
|
||||||
@ -139,7 +134,7 @@ void Application::saveParameterFile(const std::string parameterFileName)
|
|||||||
{
|
{
|
||||||
XmlWriter writer(parameterFileName);
|
XmlWriter writer(parameterFileName);
|
||||||
ObjectId id;
|
ObjectId id;
|
||||||
const unsigned int nMod = env().getNModule();
|
const unsigned int nMod = vm().getNModule();
|
||||||
|
|
||||||
LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl;
|
LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl;
|
||||||
write(writer, "parameters", getPar());
|
write(writer, "parameters", getPar());
|
||||||
@ -147,10 +142,10 @@ void Application::saveParameterFile(const std::string parameterFileName)
|
|||||||
for (unsigned int i = 0; i < nMod; ++i)
|
for (unsigned int i = 0; i < nMod; ++i)
|
||||||
{
|
{
|
||||||
push(writer, "module");
|
push(writer, "module");
|
||||||
id.name = env().getModuleName(i);
|
id.name = vm().getModuleName(i);
|
||||||
id.type = env().getModule(i)->getRegisteredName();
|
id.type = vm().getModule(i)->getRegisteredName();
|
||||||
write(writer, "id", id);
|
write(writer, "id", id);
|
||||||
env().getModule(i)->saveParameters(writer, "options");
|
vm().getModule(i)->saveParameters(writer, "options");
|
||||||
pop(writer);
|
pop(writer);
|
||||||
}
|
}
|
||||||
pop(writer);
|
pop(writer);
|
||||||
@ -158,95 +153,13 @@ void Application::saveParameterFile(const std::string parameterFileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// schedule computation ////////////////////////////////////////////////////////
|
// schedule computation ////////////////////////////////////////////////////////
|
||||||
#define MEM_MSG(size)\
|
|
||||||
sizeString((size)*locVol_) << " (" << sizeString(size) << "/site)"
|
|
||||||
|
|
||||||
#define DEFINE_MEMPEAK \
|
|
||||||
GeneticScheduler<unsigned int>::ObjFunc memPeak = \
|
|
||||||
[this](const std::vector<unsigned int> &program)\
|
|
||||||
{\
|
|
||||||
unsigned int memPeak;\
|
|
||||||
bool msg;\
|
|
||||||
\
|
|
||||||
msg = HadronsLogMessage.isActive();\
|
|
||||||
HadronsLogMessage.Active(false);\
|
|
||||||
env().dryRun(true);\
|
|
||||||
memPeak = env().executeProgram(program);\
|
|
||||||
env().dryRun(false);\
|
|
||||||
env().freeAll();\
|
|
||||||
HadronsLogMessage.Active(true);\
|
|
||||||
\
|
|
||||||
return memPeak;\
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::schedule(void)
|
void Application::schedule(void)
|
||||||
{
|
{
|
||||||
DEFINE_MEMPEAK;
|
if (!scheduled_ and !loadedSchedule_)
|
||||||
|
|
||||||
// build module dependency graph
|
|
||||||
LOG(Message) << "Building module graph..." << std::endl;
|
|
||||||
auto graph = env().makeModuleGraph();
|
|
||||||
auto con = graph.getConnectedComponents();
|
|
||||||
|
|
||||||
// constrained topological sort using a genetic algorithm
|
|
||||||
LOG(Message) << "Scheduling computation..." << std::endl;
|
|
||||||
LOG(Message) << " #module= " << graph.size() << std::endl;
|
|
||||||
LOG(Message) << " population size= " << par_.genetic.popSize << std::endl;
|
|
||||||
LOG(Message) << " max. generation= " << par_.genetic.maxGen << std::endl;
|
|
||||||
LOG(Message) << " max. cst. generation= " << par_.genetic.maxCstGen << std::endl;
|
|
||||||
LOG(Message) << " mutation rate= " << par_.genetic.mutationRate << std::endl;
|
|
||||||
|
|
||||||
unsigned int k = 0, gen, prevPeak, nCstPeak = 0;
|
|
||||||
std::random_device rd;
|
|
||||||
GeneticScheduler<unsigned int>::Parameters par;
|
|
||||||
|
|
||||||
par.popSize = par_.genetic.popSize;
|
|
||||||
par.mutationRate = par_.genetic.mutationRate;
|
|
||||||
par.seed = rd();
|
|
||||||
memPeak_ = 0;
|
|
||||||
CartesianCommunicator::BroadcastWorld(0, &(par.seed), sizeof(par.seed));
|
|
||||||
for (unsigned int i = 0; i < con.size(); ++i)
|
|
||||||
{
|
{
|
||||||
GeneticScheduler<unsigned int> scheduler(con[i], memPeak, par);
|
program_ = vm().schedule(par_.genetic);
|
||||||
|
scheduled_ = true;
|
||||||
gen = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
LOG(Debug) << "Generation " << gen << ":" << std::endl;
|
|
||||||
scheduler.nextGeneration();
|
|
||||||
if (gen != 0)
|
|
||||||
{
|
|
||||||
if (prevPeak == scheduler.getMinValue())
|
|
||||||
{
|
|
||||||
nCstPeak++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nCstPeak = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prevPeak = scheduler.getMinValue();
|
|
||||||
if (gen % 10 == 0)
|
|
||||||
{
|
|
||||||
LOG(Iterative) << "Generation " << gen << ": "
|
|
||||||
<< MEM_MSG(scheduler.getMinValue()) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
gen++;
|
|
||||||
} while ((gen < par_.genetic.maxGen)
|
|
||||||
and (nCstPeak < par_.genetic.maxCstGen));
|
|
||||||
auto &t = scheduler.getMinSchedule();
|
|
||||||
if (scheduler.getMinValue() > memPeak_)
|
|
||||||
{
|
|
||||||
memPeak_ = scheduler.getMinValue();
|
|
||||||
}
|
|
||||||
for (unsigned int j = 0; j < t.size(); ++j)
|
|
||||||
{
|
|
||||||
program_.push_back(t[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
scheduled_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::saveSchedule(const std::string filename)
|
void Application::saveSchedule(const std::string filename)
|
||||||
@ -256,21 +169,19 @@ void Application::saveSchedule(const std::string filename)
|
|||||||
|
|
||||||
if (!scheduled_)
|
if (!scheduled_)
|
||||||
{
|
{
|
||||||
HADRON_ERROR("Computation not scheduled");
|
HADRON_ERROR(Definition, "Computation not scheduled");
|
||||||
}
|
}
|
||||||
LOG(Message) << "Saving current schedule to '" << filename << "'..."
|
LOG(Message) << "Saving current schedule to '" << filename << "'..."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (auto address: program_)
|
for (auto address: program_)
|
||||||
{
|
{
|
||||||
program.push_back(env().getModuleName(address));
|
program.push_back(vm().getModuleName(address));
|
||||||
}
|
}
|
||||||
write(writer, "schedule", program);
|
write(writer, "schedule", program);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadSchedule(const std::string filename)
|
void Application::loadSchedule(const std::string filename)
|
||||||
{
|
{
|
||||||
DEFINE_MEMPEAK;
|
|
||||||
|
|
||||||
TextReader reader(filename);
|
TextReader reader(filename);
|
||||||
std::vector<std::string> program;
|
std::vector<std::string> program;
|
||||||
|
|
||||||
@ -280,24 +191,24 @@ void Application::loadSchedule(const std::string filename)
|
|||||||
program_.clear();
|
program_.clear();
|
||||||
for (auto &name: program)
|
for (auto &name: program)
|
||||||
{
|
{
|
||||||
program_.push_back(env().getModuleAddress(name));
|
program_.push_back(vm().getModuleAddress(name));
|
||||||
}
|
}
|
||||||
scheduled_ = true;
|
loadedSchedule_ = true;
|
||||||
memPeak_ = memPeak(program_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::printSchedule(void)
|
void Application::printSchedule(void)
|
||||||
{
|
{
|
||||||
if (!scheduled_)
|
if (!scheduled_)
|
||||||
{
|
{
|
||||||
HADRON_ERROR("Computation not scheduled");
|
HADRON_ERROR(Definition, "Computation not scheduled");
|
||||||
}
|
}
|
||||||
LOG(Message) << "Schedule (memory peak: " << MEM_MSG(memPeak_) << "):"
|
auto peak = vm().memoryNeeded(program_);
|
||||||
|
LOG(Message) << "Schedule (memory needed: " << sizeString(peak) << "):"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (unsigned int i = 0; i < program_.size(); ++i)
|
for (unsigned int i = 0; i < program_.size(); ++i)
|
||||||
{
|
{
|
||||||
LOG(Message) << std::setw(4) << i + 1 << ": "
|
LOG(Message) << std::setw(4) << i + 1 << ": "
|
||||||
<< env().getModuleName(program_[i]) << std::endl;
|
<< vm().getModuleName(program_[i]) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,8 +221,8 @@ void Application::configLoop(void)
|
|||||||
{
|
{
|
||||||
LOG(Message) << BIG_SEP << " Starting measurement for trajectory " << t
|
LOG(Message) << BIG_SEP << " Starting measurement for trajectory " << t
|
||||||
<< " " << BIG_SEP << std::endl;
|
<< " " << BIG_SEP << std::endl;
|
||||||
env().setTrajectory(t);
|
vm().setTrajectory(t);
|
||||||
env().executeProgram(program_);
|
vm().executeProgram(program_);
|
||||||
}
|
}
|
||||||
LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
|
LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
|
||||||
env().freeAll();
|
env().freeAll();
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Application.hpp
|
Source file: extras/Hadrons/Application.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -31,8 +30,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#define Hadrons_Application_hpp_
|
#define Hadrons_Application_hpp_
|
||||||
|
|
||||||
#include <Grid/Hadrons/Global.hpp>
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
#include <Grid/Hadrons/Environment.hpp>
|
#include <Grid/Hadrons/VirtualMachine.hpp>
|
||||||
#include <Grid/Hadrons/ModuleFactory.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules.hpp>
|
#include <Grid/Hadrons/Modules.hpp>
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
@ -51,25 +49,13 @@ public:
|
|||||||
unsigned int, end,
|
unsigned int, end,
|
||||||
unsigned int, step);
|
unsigned int, step);
|
||||||
};
|
};
|
||||||
class GeneticPar: Serializable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GeneticPar(void):
|
|
||||||
popSize{20}, maxGen{1000}, maxCstGen{100}, mutationRate{.1} {};
|
|
||||||
public:
|
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(GeneticPar,
|
|
||||||
unsigned int, popSize,
|
|
||||||
unsigned int, maxGen,
|
|
||||||
unsigned int, maxCstGen,
|
|
||||||
double , mutationRate);
|
|
||||||
};
|
|
||||||
class GlobalPar: Serializable
|
class GlobalPar: Serializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(GlobalPar,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(GlobalPar,
|
||||||
TrajRange, trajCounter,
|
TrajRange, trajCounter,
|
||||||
GeneticPar, genetic,
|
VirtualMachine::GeneticPar, genetic,
|
||||||
std::string, seed);
|
std::string, seed);
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
@ -100,14 +86,15 @@ public:
|
|||||||
void configLoop(void);
|
void configLoop(void);
|
||||||
private:
|
private:
|
||||||
// environment shortcut
|
// environment shortcut
|
||||||
Environment & env(void) const;
|
DEFINE_ENV_ALIAS;
|
||||||
|
// virtual machine shortcut
|
||||||
|
DEFINE_VM_ALIAS;
|
||||||
private:
|
private:
|
||||||
long unsigned int locVol_;
|
long unsigned int locVol_;
|
||||||
std::string parameterFileName_{""};
|
std::string parameterFileName_{""};
|
||||||
GlobalPar par_;
|
GlobalPar par_;
|
||||||
std::vector<unsigned int> program_;
|
VirtualMachine::Program program_;
|
||||||
Environment::Size memPeak_;
|
bool scheduled_{false}, loadedSchedule_{false};
|
||||||
bool scheduled_{false};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -117,14 +104,16 @@ private:
|
|||||||
template <typename M>
|
template <typename M>
|
||||||
void Application::createModule(const std::string name)
|
void Application::createModule(const std::string name)
|
||||||
{
|
{
|
||||||
env().createModule<M>(name);
|
vm().createModule<M>(name);
|
||||||
|
scheduled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename M>
|
template <typename M>
|
||||||
void Application::createModule(const std::string name,
|
void Application::createModule(const std::string name,
|
||||||
const typename M::Par &par)
|
const typename M::Par &par)
|
||||||
{
|
{
|
||||||
env().createModule<M>(name, par);
|
vm().createModule<M>(name, par);
|
||||||
|
scheduled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Environment.cc
|
Source file: extras/Hadrons/Environment.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -35,6 +34,9 @@ using namespace Grid;
|
|||||||
using namespace QCD;
|
using namespace QCD;
|
||||||
using namespace Hadrons;
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
#define ERROR_NO_ADDRESS(address)\
|
||||||
|
HADRON_ERROR(Definition, "no object with address " + std::to_string(address));
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Environment implementation *
|
* Environment implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -56,28 +58,6 @@ Environment::Environment(void)
|
|||||||
rng4d_.reset(new GridParallelRNG(grid4d_.get()));
|
rng4d_.reset(new GridParallelRNG(grid4d_.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// dry run /////////////////////////////////////////////////////////////////////
|
|
||||||
void Environment::dryRun(const bool isDry)
|
|
||||||
{
|
|
||||||
dryRun_ = isDry;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::isDryRun(void) const
|
|
||||||
{
|
|
||||||
return dryRun_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trajectory number ///////////////////////////////////////////////////////////
|
|
||||||
void Environment::setTrajectory(const unsigned int traj)
|
|
||||||
{
|
|
||||||
traj_ = traj;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Environment::getTrajectory(void) const
|
|
||||||
{
|
|
||||||
return traj_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// grids ///////////////////////////////////////////////////////////////////////
|
// grids ///////////////////////////////////////////////////////////////////////
|
||||||
void Environment::createGrid(const unsigned int Ls)
|
void Environment::createGrid(const unsigned int Ls)
|
||||||
{
|
{
|
||||||
@ -105,7 +85,7 @@ GridCartesian * Environment::getGrid(const unsigned int Ls) const
|
|||||||
}
|
}
|
||||||
catch(std::out_of_range &)
|
catch(std::out_of_range &)
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no grid with Ls= " << Ls);
|
HADRON_ERROR(Definition, "no grid with Ls= " + std::to_string(Ls));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +104,7 @@ GridRedBlackCartesian * Environment::getRbGrid(const unsigned int Ls) const
|
|||||||
}
|
}
|
||||||
catch(std::out_of_range &)
|
catch(std::out_of_range &)
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no red-black 5D grid with Ls= " << Ls);
|
HADRON_ERROR(Definition, "no red-black 5D grid with Ls= " + std::to_string(Ls));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +123,11 @@ int Environment::getDim(const unsigned int mu) const
|
|||||||
return dim_[mu];
|
return dim_[mu];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long int Environment::getLocalVolume(void) const
|
||||||
|
{
|
||||||
|
return locVol_;
|
||||||
|
}
|
||||||
|
|
||||||
// random number generator /////////////////////////////////////////////////////
|
// random number generator /////////////////////////////////////////////////////
|
||||||
void Environment::setSeed(const std::vector<int> &seed)
|
void Environment::setSeed(const std::vector<int> &seed)
|
||||||
{
|
{
|
||||||
@ -154,291 +139,6 @@ GridParallelRNG * Environment::get4dRng(void) const
|
|||||||
return rng4d_.get();
|
return rng4d_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// module management ///////////////////////////////////////////////////////////
|
|
||||||
void Environment::pushModule(Environment::ModPt &pt)
|
|
||||||
{
|
|
||||||
std::string name = pt->getName();
|
|
||||||
|
|
||||||
if (!hasModule(name))
|
|
||||||
{
|
|
||||||
std::vector<unsigned int> inputAddress;
|
|
||||||
unsigned int address;
|
|
||||||
ModuleInfo m;
|
|
||||||
|
|
||||||
m.data = std::move(pt);
|
|
||||||
m.type = typeIdPt(*m.data.get());
|
|
||||||
m.name = name;
|
|
||||||
auto input = m.data->getInput();
|
|
||||||
for (auto &in: input)
|
|
||||||
{
|
|
||||||
if (!hasObject(in))
|
|
||||||
{
|
|
||||||
addObject(in , -1);
|
|
||||||
}
|
|
||||||
m.input.push_back(objectAddress_[in]);
|
|
||||||
}
|
|
||||||
auto output = m.data->getOutput();
|
|
||||||
module_.push_back(std::move(m));
|
|
||||||
address = static_cast<unsigned int>(module_.size() - 1);
|
|
||||||
moduleAddress_[name] = address;
|
|
||||||
for (auto &out: output)
|
|
||||||
{
|
|
||||||
if (!hasObject(out))
|
|
||||||
{
|
|
||||||
addObject(out, address);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (object_[objectAddress_[out]].module < 0)
|
|
||||||
{
|
|
||||||
object_[objectAddress_[out]].module = address;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object '" + out
|
|
||||||
+ "' is already produced by module '"
|
|
||||||
+ module_[object_[getObjectAddress(out)].module].name
|
|
||||||
+ "' (while pushing module '" + name + "')");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("module '" + name + "' already exists");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Environment::getNModule(void) const
|
|
||||||
{
|
|
||||||
return module_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Environment::createModule(const std::string name, const std::string type,
|
|
||||||
XmlReader &reader)
|
|
||||||
{
|
|
||||||
auto &factory = ModuleFactory::getInstance();
|
|
||||||
auto pt = factory.create(type, name);
|
|
||||||
|
|
||||||
pt->parseParameters(reader, "options");
|
|
||||||
pushModule(pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleBase * Environment::getModule(const unsigned int address) const
|
|
||||||
{
|
|
||||||
if (hasModule(address))
|
|
||||||
{
|
|
||||||
return module_[address].data.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no module with address " + std::to_string(address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleBase * Environment::getModule(const std::string name) const
|
|
||||||
{
|
|
||||||
return getModule(getModuleAddress(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Environment::getModuleAddress(const std::string name) const
|
|
||||||
{
|
|
||||||
if (hasModule(name))
|
|
||||||
{
|
|
||||||
return moduleAddress_.at(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no module with name '" + name + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Environment::getModuleName(const unsigned int address) const
|
|
||||||
{
|
|
||||||
if (hasModule(address))
|
|
||||||
{
|
|
||||||
return module_[address].name;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no module with address " + std::to_string(address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Environment::getModuleType(const unsigned int address) const
|
|
||||||
{
|
|
||||||
if (hasModule(address))
|
|
||||||
{
|
|
||||||
return typeName(module_[address].type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no module with address " + std::to_string(address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Environment::getModuleType(const std::string name) const
|
|
||||||
{
|
|
||||||
return getModuleType(getModuleAddress(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Environment::getModuleNamespace(const unsigned int address) const
|
|
||||||
{
|
|
||||||
std::string type = getModuleType(address), ns;
|
|
||||||
|
|
||||||
auto pos2 = type.rfind("::");
|
|
||||||
auto pos1 = type.rfind("::", pos2 - 2);
|
|
||||||
|
|
||||||
return type.substr(pos1 + 2, pos2 - pos1 - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Environment::getModuleNamespace(const std::string name) const
|
|
||||||
{
|
|
||||||
return getModuleNamespace(getModuleAddress(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::hasModule(const unsigned int address) const
|
|
||||||
{
|
|
||||||
return (address < module_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::hasModule(const std::string name) const
|
|
||||||
{
|
|
||||||
return (moduleAddress_.find(name) != moduleAddress_.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
Graph<unsigned int> Environment::makeModuleGraph(void) const
|
|
||||||
{
|
|
||||||
Graph<unsigned int> moduleGraph;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < module_.size(); ++i)
|
|
||||||
{
|
|
||||||
moduleGraph.addVertex(i);
|
|
||||||
for (auto &j: module_[i].input)
|
|
||||||
{
|
|
||||||
moduleGraph.addEdge(object_[j].module, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return moduleGraph;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BIG_SEP "==============="
|
|
||||||
#define SEP "---------------"
|
|
||||||
#define MEM_MSG(size)\
|
|
||||||
sizeString((size)*locVol_) << " (" << sizeString(size) << "/site)"
|
|
||||||
|
|
||||||
Environment::Size
|
|
||||||
Environment::executeProgram(const std::vector<unsigned int> &p)
|
|
||||||
{
|
|
||||||
Size memPeak = 0, sizeBefore, sizeAfter;
|
|
||||||
std::vector<std::set<unsigned int>> freeProg;
|
|
||||||
bool continueCollect, nothingFreed;
|
|
||||||
|
|
||||||
// build garbage collection schedule
|
|
||||||
freeProg.resize(p.size());
|
|
||||||
for (unsigned int i = 0; i < object_.size(); ++i)
|
|
||||||
{
|
|
||||||
auto pred = [i, this](const unsigned int j)
|
|
||||||
{
|
|
||||||
auto &in = module_[j].input;
|
|
||||||
auto it = std::find(in.begin(), in.end(), i);
|
|
||||||
|
|
||||||
return (it != in.end()) or (j == object_[i].module);
|
|
||||||
};
|
|
||||||
auto it = std::find_if(p.rbegin(), p.rend(), pred);
|
|
||||||
if (it != p.rend())
|
|
||||||
{
|
|
||||||
freeProg[p.rend() - it - 1].insert(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// program execution
|
|
||||||
for (unsigned int i = 0; i < p.size(); ++i)
|
|
||||||
{
|
|
||||||
// execute module
|
|
||||||
if (!isDryRun())
|
|
||||||
{
|
|
||||||
LOG(Message) << SEP << " Measurement step " << i+1 << "/"
|
|
||||||
<< p.size() << " (module '" << module_[p[i]].name
|
|
||||||
<< "') " << SEP << std::endl;
|
|
||||||
}
|
|
||||||
(*module_[p[i]].data)();
|
|
||||||
sizeBefore = getTotalSize();
|
|
||||||
// print used memory after execution
|
|
||||||
if (!isDryRun())
|
|
||||||
{
|
|
||||||
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
if (sizeBefore > memPeak)
|
|
||||||
{
|
|
||||||
memPeak = sizeBefore;
|
|
||||||
}
|
|
||||||
// garbage collection for step i
|
|
||||||
if (!isDryRun())
|
|
||||||
{
|
|
||||||
LOG(Message) << "Garbage collection..." << std::endl;
|
|
||||||
}
|
|
||||||
nothingFreed = true;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
continueCollect = false;
|
|
||||||
auto toFree = freeProg[i];
|
|
||||||
for (auto &j: toFree)
|
|
||||||
{
|
|
||||||
// continue garbage collection while there are still
|
|
||||||
// objects without owners
|
|
||||||
continueCollect = continueCollect or !hasOwners(j);
|
|
||||||
if(freeObject(j))
|
|
||||||
{
|
|
||||||
// if an object has been freed, remove it from
|
|
||||||
// the garbage collection schedule
|
|
||||||
freeProg[i].erase(j);
|
|
||||||
nothingFreed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (continueCollect);
|
|
||||||
// any remaining objects in step i garbage collection schedule
|
|
||||||
// is scheduled for step i + 1
|
|
||||||
if (i + 1 < p.size())
|
|
||||||
{
|
|
||||||
for (auto &j: freeProg[i])
|
|
||||||
{
|
|
||||||
freeProg[i + 1].insert(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// print used memory after garbage collection if necessary
|
|
||||||
if (!isDryRun())
|
|
||||||
{
|
|
||||||
sizeAfter = getTotalSize();
|
|
||||||
if (sizeBefore != sizeAfter)
|
|
||||||
{
|
|
||||||
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(Message) << "Nothing to free" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return memPeak;
|
|
||||||
}
|
|
||||||
|
|
||||||
Environment::Size Environment::executeProgram(const std::vector<std::string> &p)
|
|
||||||
{
|
|
||||||
std::vector<unsigned int> pAddress;
|
|
||||||
|
|
||||||
for (auto &n: p)
|
|
||||||
{
|
|
||||||
pAddress.push_back(getModuleAddress(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
return executeProgram(pAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// general memory management ///////////////////////////////////////////////////
|
// general memory management ///////////////////////////////////////////////////
|
||||||
void Environment::addObject(const std::string name, const int moduleAddress)
|
void Environment::addObject(const std::string name, const int moduleAddress)
|
||||||
{
|
{
|
||||||
@ -448,46 +148,25 @@ void Environment::addObject(const std::string name, const int moduleAddress)
|
|||||||
|
|
||||||
info.name = name;
|
info.name = name;
|
||||||
info.module = moduleAddress;
|
info.module = moduleAddress;
|
||||||
|
info.data = nullptr;
|
||||||
object_.push_back(std::move(info));
|
object_.push_back(std::move(info));
|
||||||
objectAddress_[name] = static_cast<unsigned int>(object_.size() - 1);
|
objectAddress_[name] = static_cast<unsigned int>(object_.size() - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("object '" + name + "' already exists");
|
HADRON_ERROR(Definition, "object '" + name + "' already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::registerObject(const unsigned int address,
|
void Environment::setObjectModule(const unsigned int objAddress,
|
||||||
const unsigned int size, const unsigned int Ls)
|
const int modAddress)
|
||||||
{
|
{
|
||||||
if (!hasRegisteredObject(address))
|
object_[objAddress].module = modAddress;
|
||||||
{
|
|
||||||
if (hasObject(address))
|
|
||||||
{
|
|
||||||
object_[address].size = size;
|
|
||||||
object_[address].Ls = Ls;
|
|
||||||
object_[address].isRegistered = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address)
|
|
||||||
+ " already registered");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::registerObject(const std::string name,
|
unsigned int Environment::getMaxAddress(void) const
|
||||||
const unsigned int size, const unsigned int Ls)
|
|
||||||
{
|
{
|
||||||
if (!hasObject(name))
|
return object_.size();
|
||||||
{
|
|
||||||
addObject(name);
|
|
||||||
}
|
|
||||||
registerObject(getObjectAddress(name), size, Ls);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Environment::getObjectAddress(const std::string name) const
|
unsigned int Environment::getObjectAddress(const std::string name) const
|
||||||
@ -498,7 +177,7 @@ unsigned int Environment::getObjectAddress(const std::string name) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with name '" + name + "'");
|
HADRON_ERROR(Definition, "no object with name '" + name + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,13 +189,13 @@ std::string Environment::getObjectName(const unsigned int address) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
ERROR_NO_ADDRESS(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Environment::getObjectType(const unsigned int address) const
|
std::string Environment::getObjectType(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasRegisteredObject(address))
|
if (hasObject(address))
|
||||||
{
|
{
|
||||||
if (object_[address].type)
|
if (object_[address].type)
|
||||||
{
|
{
|
||||||
@ -527,14 +206,9 @@ std::string Environment::getObjectType(const unsigned int address) const
|
|||||||
return "<no type>";
|
return "<no type>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hasObject(address))
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address)
|
|
||||||
+ " exists but is not registered");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
ERROR_NO_ADDRESS(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,18 +219,13 @@ std::string Environment::getObjectType(const std::string name) const
|
|||||||
|
|
||||||
Environment::Size Environment::getObjectSize(const unsigned int address) const
|
Environment::Size Environment::getObjectSize(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasRegisteredObject(address))
|
if (hasObject(address))
|
||||||
{
|
{
|
||||||
return object_[address].size;
|
return object_[address].size;
|
||||||
}
|
}
|
||||||
else if (hasObject(address))
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address)
|
|
||||||
+ " exists but is not registered");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
ERROR_NO_ADDRESS(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +234,24 @@ Environment::Size Environment::getObjectSize(const std::string name) const
|
|||||||
return getObjectSize(getObjectAddress(name));
|
return getObjectSize(getObjectAddress(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Environment::getObjectModule(const unsigned int address) const
|
Environment::Storage Environment::getObjectStorage(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasObject(address))
|
||||||
|
{
|
||||||
|
return object_[address].storage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR_NO_ADDRESS(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Storage Environment::getObjectStorage(const std::string name) const
|
||||||
|
{
|
||||||
|
return getObjectStorage(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
int Environment::getObjectModule(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasObject(address))
|
if (hasObject(address))
|
||||||
{
|
{
|
||||||
@ -573,29 +259,24 @@ unsigned int Environment::getObjectModule(const unsigned int address) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
ERROR_NO_ADDRESS(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Environment::getObjectModule(const std::string name) const
|
int Environment::getObjectModule(const std::string name) const
|
||||||
{
|
{
|
||||||
return getObjectModule(getObjectAddress(name));
|
return getObjectModule(getObjectAddress(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Environment::getObjectLs(const unsigned int address) const
|
unsigned int Environment::getObjectLs(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasRegisteredObject(address))
|
if (hasObject(address))
|
||||||
{
|
{
|
||||||
return object_[address].Ls;
|
return object_[address].Ls;
|
||||||
}
|
}
|
||||||
else if (hasObject(address))
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address)
|
|
||||||
+ " exists but is not registered");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
ERROR_NO_ADDRESS(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,30 +297,6 @@ bool Environment::hasObject(const std::string name) const
|
|||||||
return ((it != objectAddress_.end()) and hasObject(it->second));
|
return ((it != objectAddress_.end()) and hasObject(it->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Environment::hasRegisteredObject(const unsigned int address) const
|
|
||||||
{
|
|
||||||
if (hasObject(address))
|
|
||||||
{
|
|
||||||
return object_[address].isRegistered;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::hasRegisteredObject(const std::string name) const
|
|
||||||
{
|
|
||||||
if (hasObject(name))
|
|
||||||
{
|
|
||||||
return hasRegisteredObject(getObjectAddress(name));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::hasCreatedObject(const unsigned int address) const
|
bool Environment::hasCreatedObject(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasObject(address))
|
if (hasObject(address))
|
||||||
@ -680,92 +337,27 @@ Environment::Size Environment::getTotalSize(void) const
|
|||||||
|
|
||||||
for (auto &o: object_)
|
for (auto &o: object_)
|
||||||
{
|
{
|
||||||
if (o.isRegistered)
|
size += o.size;
|
||||||
{
|
|
||||||
size += o.size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::addOwnership(const unsigned int owner,
|
void Environment::freeObject(const unsigned int address)
|
||||||
const unsigned int property)
|
|
||||||
{
|
{
|
||||||
if (hasObject(property))
|
if (hasCreatedObject(address))
|
||||||
{
|
{
|
||||||
object_[property].owners.insert(owner);
|
LOG(Message) << "Destroying object '" << object_[address].name
|
||||||
}
|
<< "'" << std::endl;
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no object with address " + std::to_string(property));
|
|
||||||
}
|
|
||||||
if (hasObject(owner))
|
|
||||||
{
|
|
||||||
object_[owner].properties.insert(property);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no object with address " + std::to_string(owner));
|
|
||||||
}
|
}
|
||||||
|
object_[address].size = 0;
|
||||||
|
object_[address].type = nullptr;
|
||||||
|
object_[address].data.reset(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::addOwnership(const std::string owner,
|
void Environment::freeObject(const std::string name)
|
||||||
const std::string property)
|
|
||||||
{
|
{
|
||||||
addOwnership(getObjectAddress(owner), getObjectAddress(property));
|
freeObject(getObjectAddress(name));
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::hasOwners(const unsigned int address) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (hasObject(address))
|
|
||||||
{
|
|
||||||
return (!object_[address].owners.empty());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::hasOwners(const std::string name) const
|
|
||||||
{
|
|
||||||
return hasOwners(getObjectAddress(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::freeObject(const unsigned int address)
|
|
||||||
{
|
|
||||||
if (!hasOwners(address))
|
|
||||||
{
|
|
||||||
if (!isDryRun() and object_[address].isRegistered)
|
|
||||||
{
|
|
||||||
LOG(Message) << "Destroying object '" << object_[address].name
|
|
||||||
<< "'" << std::endl;
|
|
||||||
}
|
|
||||||
for (auto &p: object_[address].properties)
|
|
||||||
{
|
|
||||||
object_[p].owners.erase(address);
|
|
||||||
}
|
|
||||||
object_[address].size = 0;
|
|
||||||
object_[address].Ls = 0;
|
|
||||||
object_[address].isRegistered = false;
|
|
||||||
object_[address].type = nullptr;
|
|
||||||
object_[address].owners.clear();
|
|
||||||
object_[address].properties.clear();
|
|
||||||
object_[address].data.reset(nullptr);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Environment::freeObject(const std::string name)
|
|
||||||
{
|
|
||||||
return freeObject(getObjectAddress(name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::freeAll(void)
|
void Environment::freeAll(void)
|
||||||
@ -776,18 +368,24 @@ void Environment::freeAll(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::printContent(void)
|
void Environment::protectObjects(const bool protect)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Modules: " << std::endl;
|
protect_ = protect;
|
||||||
for (unsigned int i = 0; i < module_.size(); ++i)
|
}
|
||||||
{
|
|
||||||
LOG(Message) << std::setw(4) << i << ": "
|
bool Environment::objectsProtected(void) const
|
||||||
<< getModuleName(i) << std::endl;
|
{
|
||||||
}
|
return protect_;
|
||||||
LOG(Message) << "Objects: " << std::endl;
|
}
|
||||||
|
|
||||||
|
// print environment content ///////////////////////////////////////////////////
|
||||||
|
void Environment::printContent(void) const
|
||||||
|
{
|
||||||
|
LOG(Debug) << "Objects: " << std::endl;
|
||||||
for (unsigned int i = 0; i < object_.size(); ++i)
|
for (unsigned int i = 0; i < object_.size(); ++i)
|
||||||
{
|
{
|
||||||
LOG(Message) << std::setw(4) << i << ": "
|
LOG(Debug) << std::setw(4) << i << ": "
|
||||||
<< getObjectName(i) << std::endl;
|
<< getObjectName(i) << " ("
|
||||||
|
<< sizeString(getObjectSize(i)) << ")" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Environment.hpp
|
Source file: extras/Hadrons/Environment.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -31,20 +30,12 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#define Hadrons_Environment_hpp_
|
#define Hadrons_Environment_hpp_
|
||||||
|
|
||||||
#include <Grid/Hadrons/Global.hpp>
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
#include <Grid/Hadrons/Graph.hpp>
|
|
||||||
|
|
||||||
#ifndef SITE_SIZE_TYPE
|
|
||||||
#define SITE_SIZE_TYPE unsigned int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Global environment *
|
* Global environment *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
// forward declaration of Module
|
|
||||||
class ModuleBase;
|
|
||||||
|
|
||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -66,123 +57,78 @@ private:
|
|||||||
std::unique_ptr<T> objPt_{nullptr};
|
std::unique_ptr<T> objPt_{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DEFINE_ENV_ALIAS \
|
||||||
|
inline Environment & env(void) const\
|
||||||
|
{\
|
||||||
|
return Environment::getInstance();\
|
||||||
|
}
|
||||||
|
|
||||||
class Environment
|
class Environment
|
||||||
{
|
{
|
||||||
SINGLETON(Environment);
|
SINGLETON(Environment);
|
||||||
public:
|
public:
|
||||||
typedef SITE_SIZE_TYPE Size;
|
typedef SITE_SIZE_TYPE Size;
|
||||||
typedef std::unique_ptr<ModuleBase> ModPt;
|
|
||||||
typedef std::unique_ptr<GridCartesian> GridPt;
|
typedef std::unique_ptr<GridCartesian> GridPt;
|
||||||
typedef std::unique_ptr<GridRedBlackCartesian> GridRbPt;
|
typedef std::unique_ptr<GridRedBlackCartesian> GridRbPt;
|
||||||
typedef std::unique_ptr<GridParallelRNG> RngPt;
|
typedef std::unique_ptr<GridParallelRNG> RngPt;
|
||||||
typedef std::unique_ptr<LatticeBase> LatticePt;
|
enum class Storage {object, cache, temporary};
|
||||||
private:
|
private:
|
||||||
struct ModuleInfo
|
|
||||||
{
|
|
||||||
const std::type_info *type{nullptr};
|
|
||||||
std::string name;
|
|
||||||
ModPt data{nullptr};
|
|
||||||
std::vector<unsigned int> input;
|
|
||||||
};
|
|
||||||
struct ObjInfo
|
struct ObjInfo
|
||||||
{
|
{
|
||||||
Size size{0};
|
Size size{0};
|
||||||
|
Storage storage{Storage::object};
|
||||||
unsigned int Ls{0};
|
unsigned int Ls{0};
|
||||||
bool isRegistered{false};
|
|
||||||
const std::type_info *type{nullptr};
|
const std::type_info *type{nullptr};
|
||||||
std::string name;
|
std::string name;
|
||||||
int module{-1};
|
int module{-1};
|
||||||
std::set<unsigned int> owners, properties;
|
|
||||||
std::unique_ptr<Object> data{nullptr};
|
std::unique_ptr<Object> data{nullptr};
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
// dry run
|
|
||||||
void dryRun(const bool isDry);
|
|
||||||
bool isDryRun(void) const;
|
|
||||||
// trajectory number
|
|
||||||
void setTrajectory(const unsigned int traj);
|
|
||||||
unsigned int getTrajectory(void) const;
|
|
||||||
// grids
|
// grids
|
||||||
void createGrid(const unsigned int Ls);
|
void createGrid(const unsigned int Ls);
|
||||||
GridCartesian * getGrid(const unsigned int Ls = 1) const;
|
GridCartesian * getGrid(const unsigned int Ls = 1) const;
|
||||||
GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const;
|
GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const;
|
||||||
std::vector<int> getDim(void) const;
|
std::vector<int> getDim(void) const;
|
||||||
int getDim(const unsigned int mu) const;
|
int getDim(const unsigned int mu) const;
|
||||||
|
unsigned long int getLocalVolume(void) const;
|
||||||
unsigned int getNd(void) const;
|
unsigned int getNd(void) const;
|
||||||
// random number generator
|
// random number generator
|
||||||
void setSeed(const std::vector<int> &seed);
|
void setSeed(const std::vector<int> &seed);
|
||||||
GridParallelRNG * get4dRng(void) const;
|
GridParallelRNG * get4dRng(void) const;
|
||||||
// module management
|
|
||||||
void pushModule(ModPt &pt);
|
|
||||||
template <typename M>
|
|
||||||
void createModule(const std::string name);
|
|
||||||
template <typename M>
|
|
||||||
void createModule(const std::string name,
|
|
||||||
const typename M::Par &par);
|
|
||||||
void createModule(const std::string name,
|
|
||||||
const std::string type,
|
|
||||||
XmlReader &reader);
|
|
||||||
unsigned int getNModule(void) const;
|
|
||||||
ModuleBase * getModule(const unsigned int address) const;
|
|
||||||
ModuleBase * getModule(const std::string name) const;
|
|
||||||
template <typename M>
|
|
||||||
M * getModule(const unsigned int address) const;
|
|
||||||
template <typename M>
|
|
||||||
M * getModule(const std::string name) const;
|
|
||||||
unsigned int getModuleAddress(const std::string name) const;
|
|
||||||
std::string getModuleName(const unsigned int address) const;
|
|
||||||
std::string getModuleType(const unsigned int address) const;
|
|
||||||
std::string getModuleType(const std::string name) const;
|
|
||||||
std::string getModuleNamespace(const unsigned int address) const;
|
|
||||||
std::string getModuleNamespace(const std::string name) const;
|
|
||||||
bool hasModule(const unsigned int address) const;
|
|
||||||
bool hasModule(const std::string name) const;
|
|
||||||
Graph<unsigned int> makeModuleGraph(void) const;
|
|
||||||
Size executeProgram(const std::vector<unsigned int> &p);
|
|
||||||
Size executeProgram(const std::vector<std::string> &p);
|
|
||||||
// general memory management
|
// general memory management
|
||||||
void addObject(const std::string name,
|
void addObject(const std::string name,
|
||||||
const int moduleAddress = -1);
|
const int moduleAddress = -1);
|
||||||
void registerObject(const unsigned int address,
|
template <typename B, typename T, typename ... Ts>
|
||||||
const unsigned int size,
|
void createDerivedObject(const std::string name,
|
||||||
const unsigned int Ls = 1);
|
const Environment::Storage storage,
|
||||||
void registerObject(const std::string name,
|
const unsigned int Ls,
|
||||||
const unsigned int size,
|
Ts && ... args);
|
||||||
const unsigned int Ls = 1);
|
template <typename T, typename ... Ts>
|
||||||
template <typename T>
|
void createObject(const std::string name,
|
||||||
unsigned int lattice4dSize(void) const;
|
const Environment::Storage storage,
|
||||||
template <typename T>
|
const unsigned int Ls,
|
||||||
void registerLattice(const unsigned int address,
|
Ts && ... args);
|
||||||
const unsigned int Ls = 1);
|
void setObjectModule(const unsigned int objAddress,
|
||||||
template <typename T>
|
const int modAddress);
|
||||||
void registerLattice(const std::string name,
|
|
||||||
const unsigned int Ls = 1);
|
|
||||||
template <typename T>
|
|
||||||
void setObject(const unsigned int address, T *object);
|
|
||||||
template <typename T>
|
|
||||||
void setObject(const std::string name, T *object);
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T * getObject(const unsigned int address) const;
|
T * getObject(const unsigned int address) const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T * getObject(const std::string name) const;
|
T * getObject(const std::string name) const;
|
||||||
template <typename T>
|
unsigned int getMaxAddress(void) const;
|
||||||
T * createLattice(const unsigned int address);
|
|
||||||
template <typename T>
|
|
||||||
T * createLattice(const std::string name);
|
|
||||||
unsigned int getObjectAddress(const std::string name) const;
|
unsigned int getObjectAddress(const std::string name) const;
|
||||||
std::string getObjectName(const unsigned int address) const;
|
std::string getObjectName(const unsigned int address) const;
|
||||||
std::string getObjectType(const unsigned int address) const;
|
std::string getObjectType(const unsigned int address) const;
|
||||||
std::string getObjectType(const std::string name) const;
|
std::string getObjectType(const std::string name) const;
|
||||||
Size getObjectSize(const unsigned int address) const;
|
Size getObjectSize(const unsigned int address) const;
|
||||||
Size getObjectSize(const std::string name) const;
|
Size getObjectSize(const std::string name) const;
|
||||||
unsigned int getObjectModule(const unsigned int address) const;
|
Storage getObjectStorage(const unsigned int address) const;
|
||||||
unsigned int getObjectModule(const std::string name) const;
|
Storage getObjectStorage(const std::string name) const;
|
||||||
|
int getObjectModule(const unsigned int address) const;
|
||||||
|
int getObjectModule(const std::string name) const;
|
||||||
unsigned int getObjectLs(const unsigned int address) const;
|
unsigned int getObjectLs(const unsigned int address) const;
|
||||||
unsigned int getObjectLs(const std::string name) const;
|
unsigned int getObjectLs(const std::string name) const;
|
||||||
bool hasObject(const unsigned int address) const;
|
bool hasObject(const unsigned int address) const;
|
||||||
bool hasObject(const std::string name) const;
|
bool hasObject(const std::string name) const;
|
||||||
bool hasRegisteredObject(const unsigned int address) const;
|
|
||||||
bool hasRegisteredObject(const std::string name) const;
|
|
||||||
bool hasCreatedObject(const unsigned int address) const;
|
bool hasCreatedObject(const unsigned int address) const;
|
||||||
bool hasCreatedObject(const std::string name) const;
|
bool hasCreatedObject(const std::string name) const;
|
||||||
bool isObject5d(const unsigned int address) const;
|
bool isObject5d(const unsigned int address) const;
|
||||||
@ -192,20 +138,17 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
bool isObjectOfType(const std::string name) const;
|
bool isObjectOfType(const std::string name) const;
|
||||||
Environment::Size getTotalSize(void) const;
|
Environment::Size getTotalSize(void) const;
|
||||||
void addOwnership(const unsigned int owner,
|
void freeObject(const unsigned int address);
|
||||||
const unsigned int property);
|
void freeObject(const std::string name);
|
||||||
void addOwnership(const std::string owner,
|
|
||||||
const std::string property);
|
|
||||||
bool hasOwners(const unsigned int address) const;
|
|
||||||
bool hasOwners(const std::string name) const;
|
|
||||||
bool freeObject(const unsigned int address);
|
|
||||||
bool freeObject(const std::string name);
|
|
||||||
void freeAll(void);
|
void freeAll(void);
|
||||||
void printContent(void);
|
void protectObjects(const bool protect);
|
||||||
|
bool objectsProtected(void) const;
|
||||||
|
// print environment content
|
||||||
|
void printContent(void) const;
|
||||||
private:
|
private:
|
||||||
// general
|
// general
|
||||||
bool dryRun_{false};
|
unsigned long int locVol_;
|
||||||
unsigned int traj_, locVol_;
|
bool protect_{true};
|
||||||
// grids
|
// grids
|
||||||
std::vector<int> dim_;
|
std::vector<int> dim_;
|
||||||
GridPt grid4d_;
|
GridPt grid4d_;
|
||||||
@ -215,11 +158,6 @@ private:
|
|||||||
unsigned int nd_;
|
unsigned int nd_;
|
||||||
// random number generator
|
// random number generator
|
||||||
RngPt rng4d_;
|
RngPt rng4d_;
|
||||||
// module and related maps
|
|
||||||
std::vector<ModuleInfo> module_;
|
|
||||||
std::map<std::string, unsigned int> moduleAddress_;
|
|
||||||
// lattice store
|
|
||||||
std::map<unsigned int, LatticePt> lattice_;
|
|
||||||
// object store
|
// object store
|
||||||
std::vector<ObjInfo> object_;
|
std::vector<ObjInfo> object_;
|
||||||
std::map<std::string, unsigned int> objectAddress_;
|
std::map<std::string, unsigned int> objectAddress_;
|
||||||
@ -256,116 +194,85 @@ void Holder<T>::reset(T *pt)
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Environment template implementation *
|
* Environment template implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
// module management ///////////////////////////////////////////////////////////
|
// general memory management ///////////////////////////////////////////////////
|
||||||
template <typename M>
|
template <typename B, typename T, typename ... Ts>
|
||||||
void Environment::createModule(const std::string name)
|
void Environment::createDerivedObject(const std::string name,
|
||||||
|
const Environment::Storage storage,
|
||||||
|
const unsigned int Ls,
|
||||||
|
Ts && ... args)
|
||||||
{
|
{
|
||||||
ModPt pt(new M(name));
|
if (!hasObject(name))
|
||||||
|
|
||||||
pushModule(pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename M>
|
|
||||||
void Environment::createModule(const std::string name,
|
|
||||||
const typename M::Par &par)
|
|
||||||
{
|
|
||||||
ModPt pt(new M(name));
|
|
||||||
|
|
||||||
static_cast<M *>(pt.get())->setPar(par);
|
|
||||||
pushModule(pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename M>
|
|
||||||
M * Environment::getModule(const unsigned int address) const
|
|
||||||
{
|
|
||||||
if (auto *pt = dynamic_cast<M *>(getModule(address)))
|
|
||||||
{
|
{
|
||||||
return pt;
|
addObject(name);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
unsigned int address = getObjectAddress(name);
|
||||||
|
|
||||||
|
if (!object_[address].data or !objectsProtected())
|
||||||
{
|
{
|
||||||
HADRON_ERROR("module '" + module_[address].name
|
MemoryStats memStats;
|
||||||
+ "' does not have type " + typeid(M).name()
|
|
||||||
+ "(object type: " + getModuleType(address) + ")");
|
if (!MemoryProfiler::stats)
|
||||||
|
{
|
||||||
|
MemoryProfiler::stats = &memStats;
|
||||||
|
}
|
||||||
|
size_t initMem = MemoryProfiler::stats->currentlyAllocated;
|
||||||
|
object_[address].storage = storage;
|
||||||
|
object_[address].Ls = Ls;
|
||||||
|
object_[address].data.reset(new Holder<B>(new T(std::forward<Ts>(args)...)));
|
||||||
|
object_[address].size = MemoryProfiler::stats->maxAllocated - initMem;
|
||||||
|
object_[address].type = &typeid(T);
|
||||||
|
if (MemoryProfiler::stats == &memStats)
|
||||||
|
{
|
||||||
|
MemoryProfiler::stats = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// object already exists, no error if it is a cache, error otherwise
|
||||||
|
else if ((object_[address].storage != Storage::cache) or
|
||||||
|
(object_[address].storage != storage) or
|
||||||
|
(object_[address].name != name) or
|
||||||
|
(object_[address].type != &typeid(T)))
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "object '" + name + "' already allocated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename M>
|
template <typename T, typename ... Ts>
|
||||||
M * Environment::getModule(const std::string name) const
|
void Environment::createObject(const std::string name,
|
||||||
|
const Environment::Storage storage,
|
||||||
|
const unsigned int Ls,
|
||||||
|
Ts && ... args)
|
||||||
{
|
{
|
||||||
return getModule<M>(getModuleAddress(name));
|
createDerivedObject<T, T>(name, storage, Ls, std::forward<Ts>(args)...);
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
unsigned int Environment::lattice4dSize(void) const
|
|
||||||
{
|
|
||||||
return sizeof(typename T::vector_object)/getGrid()->Nsimd();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Environment::registerLattice(const unsigned int address,
|
|
||||||
const unsigned int Ls)
|
|
||||||
{
|
|
||||||
createGrid(Ls);
|
|
||||||
registerObject(address, Ls*lattice4dSize<T>(), Ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Environment::registerLattice(const std::string name, const unsigned int Ls)
|
|
||||||
{
|
|
||||||
createGrid(Ls);
|
|
||||||
registerObject(name, Ls*lattice4dSize<T>(), Ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Environment::setObject(const unsigned int address, T *object)
|
|
||||||
{
|
|
||||||
if (hasRegisteredObject(address))
|
|
||||||
{
|
|
||||||
object_[address].data.reset(new Holder<T>(object));
|
|
||||||
object_[address].type = &typeid(T);
|
|
||||||
}
|
|
||||||
else if (hasObject(address))
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address) +
|
|
||||||
" exists but is not registered");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Environment::setObject(const std::string name, T *object)
|
|
||||||
{
|
|
||||||
setObject(getObjectAddress(name), object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T * Environment::getObject(const unsigned int address) const
|
T * Environment::getObject(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasRegisteredObject(address))
|
if (hasObject(address))
|
||||||
{
|
{
|
||||||
if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
|
if (hasCreatedObject(address))
|
||||||
{
|
{
|
||||||
return h->getPt();
|
if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
|
||||||
|
{
|
||||||
|
return h->getPt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "object with address " + std::to_string(address) +
|
||||||
|
" does not have type '" + typeName(&typeid(T)) +
|
||||||
|
"' (has type '" + getObjectType(address) + "')");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("object with address " + std::to_string(address) +
|
HADRON_ERROR(Definition, "object with address " + std::to_string(address) +
|
||||||
" does not have type '" + typeName(&typeid(T)) +
|
" is empty");
|
||||||
"' (has type '" + getObjectType(address) + "')");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hasObject(address))
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address) +
|
|
||||||
" exists but is not registered");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
HADRON_ERROR(Definition, "no object with address " + std::to_string(address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,26 +282,10 @@ T * Environment::getObject(const std::string name) const
|
|||||||
return getObject<T>(getObjectAddress(name));
|
return getObject<T>(getObjectAddress(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T * Environment::createLattice(const unsigned int address)
|
|
||||||
{
|
|
||||||
GridCartesian *g = getGrid(getObjectLs(address));
|
|
||||||
|
|
||||||
setObject(address, new T(g));
|
|
||||||
|
|
||||||
return getObject<T>(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T * Environment::createLattice(const std::string name)
|
|
||||||
{
|
|
||||||
return createLattice<T>(getObjectAddress(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Environment::isObjectOfType(const unsigned int address) const
|
bool Environment::isObjectOfType(const unsigned int address) const
|
||||||
{
|
{
|
||||||
if (hasRegisteredObject(address))
|
if (hasObject(address))
|
||||||
{
|
{
|
||||||
if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
|
if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
|
||||||
{
|
{
|
||||||
@ -405,14 +296,9 @@ bool Environment::isObjectOfType(const unsigned int address) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (hasObject(address))
|
|
||||||
{
|
|
||||||
HADRON_ERROR("object with address " + std::to_string(address) +
|
|
||||||
" exists but is not registered");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("no object with address " + std::to_string(address));
|
HADRON_ERROR(Definition, "no object with address " + std::to_string(address));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
extras/Hadrons/Exceptions.cc
Normal file
57
extras/Hadrons/Exceptions.cc
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Exceptions.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Exceptions.hpp>
|
||||||
|
|
||||||
|
#ifndef ERR_SUFF
|
||||||
|
#define ERR_SUFF " (" + loc + ")"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONST_EXC(name, init) \
|
||||||
|
name::name(std::string msg, std::string loc)\
|
||||||
|
:init\
|
||||||
|
{}
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace Exceptions;
|
||||||
|
|
||||||
|
// logic errors
|
||||||
|
CONST_EXC(Logic, logic_error(msg + ERR_SUFF))
|
||||||
|
CONST_EXC(Definition, Logic("definition error: " + msg, loc))
|
||||||
|
CONST_EXC(Implementation, Logic("implementation error: " + msg, loc))
|
||||||
|
CONST_EXC(Range, Logic("range error: " + msg, loc))
|
||||||
|
CONST_EXC(Size, Logic("size error: " + msg, loc))
|
||||||
|
// runtime errors
|
||||||
|
CONST_EXC(Runtime, runtime_error(msg + ERR_SUFF))
|
||||||
|
CONST_EXC(Argument, Runtime("argument error: " + msg, loc))
|
||||||
|
CONST_EXC(Io, Runtime("IO error: " + msg, loc))
|
||||||
|
CONST_EXC(Memory, Runtime("memory error: " + msg, loc))
|
||||||
|
CONST_EXC(Parsing, Runtime("parsing error: " + msg, loc))
|
||||||
|
CONST_EXC(Program, Runtime("program error: " + msg, loc))
|
||||||
|
CONST_EXC(System, Runtime("system error: " + msg, loc))
|
72
extras/Hadrons/Exceptions.hpp
Normal file
72
extras/Hadrons/Exceptions.hpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Exceptions.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_Exceptions_hpp_
|
||||||
|
#define Hadrons_Exceptions_hpp_
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#ifndef Hadrons_Global_hpp_
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SRC_LOC std::string(__FUNCTION__) + " at " + std::string(__FILE__) + ":"\
|
||||||
|
+ std::to_string(__LINE__)
|
||||||
|
#define HADRON_ERROR(exc, msg)\
|
||||||
|
LOG(Error) << msg << std::endl;\
|
||||||
|
throw(Exceptions::exc(msg, SRC_LOC));
|
||||||
|
|
||||||
|
#define DECL_EXC(name, base) \
|
||||||
|
class name: public base\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
name(std::string msg, std::string loc);\
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
namespace Exceptions
|
||||||
|
{
|
||||||
|
// logic errors
|
||||||
|
DECL_EXC(Logic, std::logic_error);
|
||||||
|
DECL_EXC(Definition, Logic);
|
||||||
|
DECL_EXC(Implementation, Logic);
|
||||||
|
DECL_EXC(Range, Logic);
|
||||||
|
DECL_EXC(Size, Logic);
|
||||||
|
// runtime errors
|
||||||
|
DECL_EXC(Runtime, std::runtime_error);
|
||||||
|
DECL_EXC(Argument, Runtime);
|
||||||
|
DECL_EXC(Io, Runtime);
|
||||||
|
DECL_EXC(Memory, Runtime);
|
||||||
|
DECL_EXC(Parsing, Runtime);
|
||||||
|
DECL_EXC(Program, Runtime);
|
||||||
|
DECL_EXC(System, Runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Exceptions_hpp_
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Factory.hpp
|
Source file: extras/Hadrons/Factory.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -95,7 +94,7 @@ std::unique_ptr<T> Factory<T>::create(const std::string type,
|
|||||||
}
|
}
|
||||||
catch (std::out_of_range &)
|
catch (std::out_of_range &)
|
||||||
{
|
{
|
||||||
HADRON_ERROR("object of type '" + type + "' unknown");
|
HADRON_ERROR(Argument, "object of type '" + type + "' unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(name);
|
return func(name);
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/GeneticScheduler.hpp
|
Source file: extras/Hadrons/GeneticScheduler.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -38,13 +37,13 @@ BEGIN_HADRONS_NAMESPACE
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Scheduler based on a genetic algorithm *
|
* Scheduler based on a genetic algorithm *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
class GeneticScheduler
|
class GeneticScheduler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<T> Gene;
|
typedef std::vector<T> Gene;
|
||||||
typedef std::pair<Gene *, Gene *> GenePair;
|
typedef std::pair<Gene *, Gene *> GenePair;
|
||||||
typedef std::function<int(const Gene &)> ObjFunc;
|
typedef std::function<V(const Gene &)> ObjFunc;
|
||||||
struct Parameters
|
struct Parameters
|
||||||
{
|
{
|
||||||
double mutationRate;
|
double mutationRate;
|
||||||
@ -65,7 +64,7 @@ public:
|
|||||||
void benchmarkCrossover(const unsigned int nIt);
|
void benchmarkCrossover(const unsigned int nIt);
|
||||||
// print population
|
// print population
|
||||||
friend std::ostream & operator<<(std::ostream &out,
|
friend std::ostream & operator<<(std::ostream &out,
|
||||||
const GeneticScheduler<T> &s)
|
const GeneticScheduler<V, T> &s)
|
||||||
{
|
{
|
||||||
out << "[";
|
out << "[";
|
||||||
for (auto &p: s.population_)
|
for (auto &p: s.population_)
|
||||||
@ -87,19 +86,19 @@ private:
|
|||||||
void mutation(Gene &m, const Gene &c);
|
void mutation(Gene &m, const Gene &c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Graph<T> &graph_;
|
Graph<T> &graph_;
|
||||||
const ObjFunc &func_;
|
const ObjFunc &func_;
|
||||||
const Parameters par_;
|
const Parameters par_;
|
||||||
std::multimap<int, Gene> population_;
|
std::multimap<V, Gene> population_;
|
||||||
std::mt19937 gen_;
|
std::mt19937 gen_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* template implementation *
|
* template implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
// constructor /////////////////////////////////////////////////////////////////
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
GeneticScheduler<T>::GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
|
GeneticScheduler<V, T>::GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
|
||||||
const Parameters &par)
|
const Parameters &par)
|
||||||
: graph_(graph)
|
: graph_(graph)
|
||||||
, func_(func)
|
, func_(func)
|
||||||
@ -109,22 +108,22 @@ GeneticScheduler<T>::GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// access //////////////////////////////////////////////////////////////////////
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
const typename GeneticScheduler<T>::Gene &
|
const typename GeneticScheduler<V, T>::Gene &
|
||||||
GeneticScheduler<T>::getMinSchedule(void)
|
GeneticScheduler<V, T>::getMinSchedule(void)
|
||||||
{
|
{
|
||||||
return population_.begin()->second;
|
return population_.begin()->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
int GeneticScheduler<T>::getMinValue(void)
|
int GeneticScheduler<V, T>::getMinValue(void)
|
||||||
{
|
{
|
||||||
return population_.begin()->first;
|
return population_.begin()->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// breed a new generation //////////////////////////////////////////////////////
|
// breed a new generation //////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::nextGeneration(void)
|
void GeneticScheduler<V, T>::nextGeneration(void)
|
||||||
{
|
{
|
||||||
// random initialization of the population if necessary
|
// random initialization of the population if necessary
|
||||||
if (population_.size() != par_.popSize)
|
if (population_.size() != par_.popSize)
|
||||||
@ -158,8 +157,8 @@ void GeneticScheduler<T>::nextGeneration(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// evolution steps /////////////////////////////////////////////////////////////
|
// evolution steps /////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::initPopulation(void)
|
void GeneticScheduler<V, T>::initPopulation(void)
|
||||||
{
|
{
|
||||||
population_.clear();
|
population_.clear();
|
||||||
for (unsigned int i = 0; i < par_.popSize; ++i)
|
for (unsigned int i = 0; i < par_.popSize; ++i)
|
||||||
@ -170,8 +169,8 @@ void GeneticScheduler<T>::initPopulation(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::doCrossover(void)
|
void GeneticScheduler<V, T>::doCrossover(void)
|
||||||
{
|
{
|
||||||
auto p = selectPair();
|
auto p = selectPair();
|
||||||
Gene &p1 = *(p.first), &p2 = *(p.second);
|
Gene &p1 = *(p.first), &p2 = *(p.second);
|
||||||
@ -185,8 +184,8 @@ void GeneticScheduler<T>::doCrossover(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::doMutation(void)
|
void GeneticScheduler<V, T>::doMutation(void)
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<double> mdis(0., 1.);
|
std::uniform_real_distribution<double> mdis(0., 1.);
|
||||||
std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1);
|
std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1);
|
||||||
@ -206,40 +205,35 @@ void GeneticScheduler<T>::doMutation(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// genetic operators ///////////////////////////////////////////////////////////
|
// genetic operators ///////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
typename GeneticScheduler<T>::GenePair GeneticScheduler<T>::selectPair(void)
|
typename GeneticScheduler<V, T>::GenePair GeneticScheduler<V, T>::selectPair(void)
|
||||||
{
|
{
|
||||||
std::vector<double> prob;
|
std::vector<double> prob;
|
||||||
unsigned int ind;
|
unsigned int ind;
|
||||||
Gene *p1, *p2;
|
Gene *p1, *p2;
|
||||||
|
const double max = population_.rbegin()->first;
|
||||||
|
|
||||||
|
|
||||||
for (auto &c: population_)
|
for (auto &c: population_)
|
||||||
{
|
{
|
||||||
prob.push_back(1./c.first);
|
prob.push_back(std::exp((c.first-1.)/max));
|
||||||
}
|
}
|
||||||
do
|
std::discrete_distribution<unsigned int> dis1(prob.begin(), prob.end());
|
||||||
{
|
auto rIt = population_.begin();
|
||||||
double probCpy;
|
ind = dis1(gen_);
|
||||||
|
std::advance(rIt, ind);
|
||||||
std::discrete_distribution<unsigned int> dis1(prob.begin(), prob.end());
|
p1 = &(rIt->second);
|
||||||
auto rIt = population_.begin();
|
prob[ind] = 0.;
|
||||||
ind = dis1(gen_);
|
std::discrete_distribution<unsigned int> dis2(prob.begin(), prob.end());
|
||||||
std::advance(rIt, ind);
|
rIt = population_.begin();
|
||||||
p1 = &(rIt->second);
|
std::advance(rIt, dis2(gen_));
|
||||||
probCpy = prob[ind];
|
p2 = &(rIt->second);
|
||||||
prob[ind] = 0.;
|
|
||||||
std::discrete_distribution<unsigned int> dis2(prob.begin(), prob.end());
|
|
||||||
rIt = population_.begin();
|
|
||||||
std::advance(rIt, dis2(gen_));
|
|
||||||
p2 = &(rIt->second);
|
|
||||||
prob[ind] = probCpy;
|
|
||||||
} while (p1 == p2);
|
|
||||||
|
|
||||||
return std::make_pair(p1, p2);
|
return std::make_pair(p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::crossover(Gene &c1, Gene &c2, const Gene &p1,
|
void GeneticScheduler<V, T>::crossover(Gene &c1, Gene &c2, const Gene &p1,
|
||||||
const Gene &p2)
|
const Gene &p2)
|
||||||
{
|
{
|
||||||
Gene buf;
|
Gene buf;
|
||||||
@ -273,8 +267,8 @@ void GeneticScheduler<T>::crossover(Gene &c1, Gene &c2, const Gene &p1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::mutation(Gene &m, const Gene &c)
|
void GeneticScheduler<V, T>::mutation(Gene &m, const Gene &c)
|
||||||
{
|
{
|
||||||
Gene buf;
|
Gene buf;
|
||||||
std::uniform_int_distribution<unsigned int> dis(0, c.size() - 1);
|
std::uniform_int_distribution<unsigned int> dis(0, c.size() - 1);
|
||||||
@ -303,8 +297,8 @@ void GeneticScheduler<T>::mutation(Gene &m, const Gene &c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename V, typename T>
|
||||||
void GeneticScheduler<T>::benchmarkCrossover(const unsigned int nIt)
|
void GeneticScheduler<V, T>::benchmarkCrossover(const unsigned int nIt)
|
||||||
{
|
{
|
||||||
Gene p1, p2, c1, c2;
|
Gene p1, p2, c1, c2;
|
||||||
double neg = 0., eq = 0., pos = 0., total;
|
double neg = 0., eq = 0., pos = 0., total;
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Global.cc
|
Source file: extras/Hadrons/Global.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -39,31 +38,19 @@ HadronsLogger Hadrons::HadronsLogMessage(1,"Message");
|
|||||||
HadronsLogger Hadrons::HadronsLogIterative(1,"Iterative");
|
HadronsLogger Hadrons::HadronsLogIterative(1,"Iterative");
|
||||||
HadronsLogger Hadrons::HadronsLogDebug(1,"Debug");
|
HadronsLogger Hadrons::HadronsLogDebug(1,"Debug");
|
||||||
|
|
||||||
// pretty size formatting //////////////////////////////////////////////////////
|
void Hadrons::initLogger(void)
|
||||||
std::string Hadrons::sizeString(long unsigned int bytes)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
constexpr unsigned int bufSize = 256;
|
auto w = std::string("Hadrons").length();
|
||||||
const char *suffixes[7] = {"", "K", "M", "G", "T", "P", "E"};
|
GridLogError.setTopWidth(w);
|
||||||
char buf[256];
|
GridLogWarning.setTopWidth(w);
|
||||||
long unsigned int s = 0;
|
GridLogMessage.setTopWidth(w);
|
||||||
double count = bytes;
|
GridLogIterative.setTopWidth(w);
|
||||||
|
GridLogDebug.setTopWidth(w);
|
||||||
while (count >= 1024 && s < 7)
|
HadronsLogError.Active(GridLogError.isActive());
|
||||||
{
|
HadronsLogWarning.Active(GridLogWarning.isActive());
|
||||||
s++;
|
HadronsLogMessage.Active(GridLogMessage.isActive());
|
||||||
count /= 1024;
|
HadronsLogIterative.Active(GridLogIterative.isActive());
|
||||||
}
|
HadronsLogDebug.Active(GridLogDebug.isActive());
|
||||||
if (count - floor(count) == 0.0)
|
|
||||||
{
|
|
||||||
snprintf(buf, bufSize, "%d %sB", (int)count, suffixes[s]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(buf, bufSize, "%.1f %sB", count, suffixes[s]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type utilities //////////////////////////////////////////////////////////////
|
// type utilities //////////////////////////////////////////////////////////////
|
||||||
@ -80,3 +67,10 @@ std::string Hadrons::typeName(const std::type_info *info)
|
|||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default writers/readers /////////////////////////////////////////////////////
|
||||||
|
#ifdef HAVE_HDF5
|
||||||
|
const std::string Hadrons::resultFileExt = "h5";
|
||||||
|
#else
|
||||||
|
const std::string Hadrons::resultFileExt = "xml";
|
||||||
|
#endif
|
||||||
|
@ -4,10 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Global.hpp
|
Source file: extras/Hadrons/Global.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -35,6 +35,10 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#include <Grid/Grid.h>
|
#include <Grid/Grid.h>
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
#ifndef SITE_SIZE_TYPE
|
||||||
|
#define SITE_SIZE_TYPE size_t
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BEGIN_HADRONS_NAMESPACE \
|
#define BEGIN_HADRONS_NAMESPACE \
|
||||||
namespace Grid {\
|
namespace Grid {\
|
||||||
using namespace QCD;\
|
using namespace QCD;\
|
||||||
@ -57,17 +61,19 @@ using Grid::operator<<;
|
|||||||
#ifndef SIMPL
|
#ifndef SIMPL
|
||||||
#define SIMPL ScalarImplCR
|
#define SIMPL ScalarImplCR
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef GIMPL
|
||||||
|
#define GIMPL GimplTypesR
|
||||||
|
#endif
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
// type aliases
|
// type aliases
|
||||||
#define FERM_TYPE_ALIASES(FImpl, suffix)\
|
#define FERM_TYPE_ALIASES(FImpl, suffix)\
|
||||||
typedef FermionOperator<FImpl> FMat##suffix; \
|
typedef FermionOperator<FImpl> FMat##suffix; \
|
||||||
typedef typename FImpl::FermionField FermionField##suffix; \
|
typedef typename FImpl::FermionField FermionField##suffix; \
|
||||||
typedef typename FImpl::PropagatorField PropagatorField##suffix; \
|
typedef typename FImpl::PropagatorField PropagatorField##suffix; \
|
||||||
typedef typename FImpl::SitePropagator SitePropagator##suffix; \
|
typedef typename FImpl::SitePropagator::scalar_object SitePropagator##suffix; \
|
||||||
typedef std::vector<typename FImpl::SitePropagator::scalar_object> \
|
typedef std::vector<SitePropagator##suffix> SlicedPropagator##suffix;
|
||||||
SlicedPropagator##suffix;
|
|
||||||
|
|
||||||
#define GAUGE_TYPE_ALIASES(FImpl, suffix)\
|
#define GAUGE_TYPE_ALIASES(FImpl, suffix)\
|
||||||
typedef typename FImpl::DoubledGaugeField DoubledGaugeField##suffix;
|
typedef typename FImpl::DoubledGaugeField DoubledGaugeField##suffix;
|
||||||
@ -81,7 +87,8 @@ typedef std::function<void(FermionField##suffix &,\
|
|||||||
const FermionField##suffix &)> SolverFn##suffix;
|
const FermionField##suffix &)> SolverFn##suffix;
|
||||||
|
|
||||||
#define SINK_TYPE_ALIASES(suffix)\
|
#define SINK_TYPE_ALIASES(suffix)\
|
||||||
typedef std::function<SlicedPropagator##suffix(const PropagatorField##suffix &)> SinkFn##suffix;
|
typedef std::function<SlicedPropagator##suffix\
|
||||||
|
(const PropagatorField##suffix &)> SinkFn##suffix;
|
||||||
|
|
||||||
#define FGS_TYPE_ALIASES(FImpl, suffix)\
|
#define FGS_TYPE_ALIASES(FImpl, suffix)\
|
||||||
FERM_TYPE_ALIASES(FImpl, suffix)\
|
FERM_TYPE_ALIASES(FImpl, suffix)\
|
||||||
@ -97,11 +104,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define LOG(channel) std::cout << HadronsLog##channel
|
#define LOG(channel) std::cout << HadronsLog##channel
|
||||||
#define HADRON_ERROR(msg)\
|
|
||||||
LOG(Error) << msg << " (" << __FUNCTION__ << " at " << __FILE__ << ":"\
|
|
||||||
<< __LINE__ << ")" << std::endl;\
|
|
||||||
abort();
|
|
||||||
|
|
||||||
#define DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl;
|
#define DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl;
|
||||||
|
|
||||||
extern HadronsLogger HadronsLogError;
|
extern HadronsLogger HadronsLogError;
|
||||||
@ -110,6 +112,8 @@ extern HadronsLogger HadronsLogMessage;
|
|||||||
extern HadronsLogger HadronsLogIterative;
|
extern HadronsLogger HadronsLogIterative;
|
||||||
extern HadronsLogger HadronsLogDebug;
|
extern HadronsLogger HadronsLogDebug;
|
||||||
|
|
||||||
|
void initLogger(void);
|
||||||
|
|
||||||
// singleton pattern
|
// singleton pattern
|
||||||
#define SINGLETON(name)\
|
#define SINGLETON(name)\
|
||||||
public:\
|
public:\
|
||||||
@ -135,9 +139,6 @@ public:\
|
|||||||
private:\
|
private:\
|
||||||
name(void) = default;
|
name(void) = default;
|
||||||
|
|
||||||
// pretty size formating
|
|
||||||
std::string sizeString(long unsigned int bytes);
|
|
||||||
|
|
||||||
// type utilities
|
// type utilities
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const std::type_info * typeIdPt(const T &x)
|
const std::type_info * typeIdPt(const T &x)
|
||||||
@ -166,14 +167,21 @@ std::string typeName(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// default writers/readers
|
// default writers/readers
|
||||||
|
extern const std::string resultFileExt;
|
||||||
|
|
||||||
#ifdef HAVE_HDF5
|
#ifdef HAVE_HDF5
|
||||||
typedef Hdf5Reader CorrReader;
|
typedef Hdf5Reader ResultReader;
|
||||||
typedef Hdf5Writer CorrWriter;
|
typedef Hdf5Writer ResultWriter;
|
||||||
#else
|
#else
|
||||||
typedef XmlReader CorrReader;
|
typedef XmlReader ResultReader;
|
||||||
typedef XmlWriter CorrWriter;
|
typedef XmlWriter ResultWriter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RESULT_FILE_NAME(name) \
|
||||||
|
name + "." + std::to_string(vm().getTrajectory()) + "." + resultFileExt
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Exceptions.hpp>
|
||||||
|
|
||||||
#endif // Hadrons_Global_hpp_
|
#endif // Hadrons_Global_hpp_
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Graph.hpp
|
Source file: extras/Hadrons/Graph.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -185,7 +184,7 @@ void Graph<T>::removeVertex(const T &value)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("vertex " << value << " does not exists");
|
HADRON_ERROR(Range, "vertex does not exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove all edges containing the vertex
|
// remove all edges containing the vertex
|
||||||
@ -214,7 +213,7 @@ void Graph<T>::removeEdge(const Edge &e)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("edge " << e << " does not exists");
|
HADRON_ERROR(Range, "edge does not exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +259,7 @@ void Graph<T>::mark(const T &value, const bool doMark)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("vertex " << value << " does not exists");
|
HADRON_ERROR(Range, "vertex does not exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +297,7 @@ bool Graph<T>::isMarked(const T &value) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HADRON_ERROR("vertex " << value << " does not exists");
|
HADRON_ERROR(Range, "vertex does not exists");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -430,7 +429,7 @@ std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
|
|||||||
{
|
{
|
||||||
return ((e.first == value) or (e.second == value));
|
return ((e.first == value) or (e.second == value));
|
||||||
};
|
};
|
||||||
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
auto eIt = std::find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
while (eIt != edgeSet_.end())
|
while (eIt != edgeSet_.end())
|
||||||
{
|
{
|
||||||
@ -442,7 +441,7 @@ std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
|
|||||||
{
|
{
|
||||||
adjacentVertex.push_back((*eIt).first);
|
adjacentVertex.push_back((*eIt).first);
|
||||||
}
|
}
|
||||||
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
eIt = std::find_if(++eIt, edgeSet_.end(), pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return adjacentVertex;
|
return adjacentVertex;
|
||||||
@ -458,12 +457,12 @@ std::vector<T> Graph<T>::getChildren(const T &value) const
|
|||||||
{
|
{
|
||||||
return (e.first == value);
|
return (e.first == value);
|
||||||
};
|
};
|
||||||
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
auto eIt = std::find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
while (eIt != edgeSet_.end())
|
while (eIt != edgeSet_.end())
|
||||||
{
|
{
|
||||||
child.push_back((*eIt).second);
|
child.push_back((*eIt).second);
|
||||||
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
eIt = std::find_if(++eIt, edgeSet_.end(), pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
@ -479,12 +478,12 @@ std::vector<T> Graph<T>::getParents(const T &value) const
|
|||||||
{
|
{
|
||||||
return (e.second == value);
|
return (e.second == value);
|
||||||
};
|
};
|
||||||
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
auto eIt = std::find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
while (eIt != edgeSet_.end())
|
while (eIt != edgeSet_.end())
|
||||||
{
|
{
|
||||||
parent.push_back((*eIt).first);
|
parent.push_back((*eIt).first);
|
||||||
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
eIt = std::find_if(++eIt, edgeSet_.end(), pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
@ -544,7 +543,7 @@ std::vector<T> Graph<T>::topoSort(void)
|
|||||||
{
|
{
|
||||||
if (tmpMarked.at(v))
|
if (tmpMarked.at(v))
|
||||||
{
|
{
|
||||||
HADRON_ERROR("cannot topologically sort a cyclic graph");
|
HADRON_ERROR(Range, "cannot topologically sort a cyclic graph");
|
||||||
}
|
}
|
||||||
if (!isMarked(v))
|
if (!isMarked(v))
|
||||||
{
|
{
|
||||||
@ -603,7 +602,7 @@ std::vector<T> Graph<T>::topoSort(Gen &gen)
|
|||||||
{
|
{
|
||||||
if (tmpMarked.at(v))
|
if (tmpMarked.at(v))
|
||||||
{
|
{
|
||||||
HADRON_ERROR("cannot topologically sort a cyclic graph");
|
HADRON_ERROR(Range, "cannot topologically sort a cyclic graph");
|
||||||
}
|
}
|
||||||
if (!isMarked(v))
|
if (!isMarked(v))
|
||||||
{
|
{
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/HadronsXmlRun.cc
|
Source file: extras/Hadrons/HadronsXmlRun.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -55,12 +54,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// initialization
|
// initialization
|
||||||
Grid_init(&argc, &argv);
|
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;
|
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
Application application(parameterFileName);
|
Application application(parameterFileName);
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/HadronsXmlSchedule.cc
|
Source file: extras/Hadrons/HadronsXmlSchedule.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -49,12 +48,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// initialization
|
// initialization
|
||||||
Grid_init(&argc, &argv);
|
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;
|
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
Application application;
|
Application application;
|
||||||
|
@ -7,20 +7,24 @@ libHadrons_a_SOURCES = \
|
|||||||
$(modules_cc) \
|
$(modules_cc) \
|
||||||
Application.cc \
|
Application.cc \
|
||||||
Environment.cc \
|
Environment.cc \
|
||||||
|
Exceptions.cc \
|
||||||
Global.cc \
|
Global.cc \
|
||||||
Module.cc
|
Module.cc \
|
||||||
|
VirtualMachine.cc
|
||||||
libHadrons_adir = $(pkgincludedir)/Hadrons
|
libHadrons_adir = $(pkgincludedir)/Hadrons
|
||||||
nobase_libHadrons_a_HEADERS = \
|
nobase_libHadrons_a_HEADERS = \
|
||||||
$(modules_hpp) \
|
$(modules_hpp) \
|
||||||
Application.hpp \
|
Application.hpp \
|
||||||
Environment.hpp \
|
Environment.hpp \
|
||||||
|
Exceptions.hpp \
|
||||||
Factory.hpp \
|
Factory.hpp \
|
||||||
GeneticScheduler.hpp \
|
GeneticScheduler.hpp \
|
||||||
Global.hpp \
|
Global.hpp \
|
||||||
Graph.hpp \
|
Graph.hpp \
|
||||||
Module.hpp \
|
Module.hpp \
|
||||||
Modules.hpp \
|
Modules.hpp \
|
||||||
ModuleFactory.hpp
|
ModuleFactory.hpp \
|
||||||
|
VirtualMachine.hpp
|
||||||
|
|
||||||
HadronsXmlRun_SOURCES = HadronsXmlRun.cc
|
HadronsXmlRun_SOURCES = HadronsXmlRun.cc
|
||||||
HadronsXmlRun_LDADD = libHadrons.a -lGrid
|
HadronsXmlRun_LDADD = libHadrons.a -lGrid
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Module.cc
|
Source file: extras/Hadrons/Module.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -39,7 +38,6 @@ using namespace Hadrons;
|
|||||||
// constructor /////////////////////////////////////////////////////////////////
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
ModuleBase::ModuleBase(const std::string name)
|
ModuleBase::ModuleBase(const std::string name)
|
||||||
: name_(name)
|
: name_(name)
|
||||||
, env_(Environment::getInstance())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// access //////////////////////////////////////////////////////////////////////
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
@ -48,15 +46,10 @@ std::string ModuleBase::getName(void) const
|
|||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment & ModuleBase::env(void) const
|
|
||||||
{
|
|
||||||
return env_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get factory registration name if available
|
// get factory registration name if available
|
||||||
std::string ModuleBase::getRegisteredName(void)
|
std::string ModuleBase::getRegisteredName(void)
|
||||||
{
|
{
|
||||||
HADRON_ERROR("module '" + getName() + "' has a type not registered"
|
HADRON_ERROR(Definition, "module '" + getName() + "' has no registered type"
|
||||||
+ " in the factory");
|
+ " in the factory");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,8 +57,5 @@ std::string ModuleBase::getRegisteredName(void)
|
|||||||
void ModuleBase::operator()(void)
|
void ModuleBase::operator()(void)
|
||||||
{
|
{
|
||||||
setup();
|
setup();
|
||||||
if (!env().isDryRun())
|
execute();
|
||||||
{
|
|
||||||
execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Module.hpp
|
Source file: extras/Hadrons/Module.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -31,7 +30,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#define Hadrons_Module_hpp_
|
#define Hadrons_Module_hpp_
|
||||||
|
|
||||||
#include <Grid/Hadrons/Global.hpp>
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
#include <Grid/Hadrons/Environment.hpp>
|
#include <Grid/Hadrons/VirtualMachine.hpp>
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
@ -87,6 +86,56 @@ public:\
|
|||||||
static ns##mod##ModuleRegistrar ns##mod##ModuleRegistrarInstance;
|
static ns##mod##ModuleRegistrar ns##mod##ModuleRegistrarInstance;
|
||||||
|
|
||||||
#define ARG(...) __VA_ARGS__
|
#define ARG(...) __VA_ARGS__
|
||||||
|
#define MACRO_REDIRECT(arg1, arg2, arg3, macro, ...) macro
|
||||||
|
|
||||||
|
#define envGet(type, name)\
|
||||||
|
*env().template getObject<type>(name)
|
||||||
|
|
||||||
|
#define envGetTmp(type, var)\
|
||||||
|
type &var = *env().template getObject<type>(getName() + "_tmp_" + #var)
|
||||||
|
|
||||||
|
#define envHasType(type, name)\
|
||||||
|
env().template isObjectOfType<type>(name)
|
||||||
|
|
||||||
|
#define envCreate(type, name, Ls, ...)\
|
||||||
|
env().template createObject<type>(name, Environment::Storage::object, Ls, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define envCreateDerived(base, type, name, Ls, ...)\
|
||||||
|
env().template createDerivedObject<base, type>(name, Environment::Storage::object, Ls, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define envCreateLat4(type, name)\
|
||||||
|
envCreate(type, name, 1, env().getGrid())
|
||||||
|
|
||||||
|
#define envCreateLat5(type, name, Ls)\
|
||||||
|
envCreate(type, name, Ls, env().getGrid(Ls))
|
||||||
|
|
||||||
|
#define envCreateLat(...)\
|
||||||
|
MACRO_REDIRECT(__VA_ARGS__, envCreateLat5, envCreateLat4)(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define envCache(type, name, Ls, ...)\
|
||||||
|
env().template createObject<type>(name, Environment::Storage::cache, Ls, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define envCacheLat4(type, name)\
|
||||||
|
envCache(type, name, 1, env().getGrid())
|
||||||
|
|
||||||
|
#define envCacheLat5(type, name, Ls)\
|
||||||
|
envCache(type, name, Ls, env().getGrid(Ls))
|
||||||
|
|
||||||
|
#define envCacheLat(...)\
|
||||||
|
MACRO_REDIRECT(__VA_ARGS__, envCacheLat5, envCacheLat4)(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define envTmp(type, name, Ls, ...)\
|
||||||
|
env().template createObject<type>(getName() + "_tmp_" + name, \
|
||||||
|
Environment::Storage::temporary, Ls, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define envTmpLat4(type, name)\
|
||||||
|
envTmp(type, name, 1, env().getGrid())
|
||||||
|
|
||||||
|
#define envTmpLat5(type, name, Ls)\
|
||||||
|
envTmp(type, name, Ls, env().getGrid(Ls))
|
||||||
|
|
||||||
|
#define envTmpLat(...)\
|
||||||
|
MACRO_REDIRECT(__VA_ARGS__, envTmpLat5, envTmpLat4)(__VA_ARGS__)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Module class *
|
* Module class *
|
||||||
@ -101,23 +150,30 @@ public:
|
|||||||
virtual ~ModuleBase(void) = default;
|
virtual ~ModuleBase(void) = default;
|
||||||
// access
|
// access
|
||||||
std::string getName(void) const;
|
std::string getName(void) const;
|
||||||
Environment &env(void) const;
|
|
||||||
// get factory registration name if available
|
// get factory registration name if available
|
||||||
virtual std::string getRegisteredName(void);
|
virtual std::string getRegisteredName(void);
|
||||||
// dependencies/products
|
// dependencies/products
|
||||||
virtual std::vector<std::string> getInput(void) = 0;
|
virtual std::vector<std::string> getInput(void) = 0;
|
||||||
|
virtual std::vector<std::string> getReference(void)
|
||||||
|
{
|
||||||
|
return std::vector<std::string>(0);
|
||||||
|
};
|
||||||
virtual std::vector<std::string> getOutput(void) = 0;
|
virtual std::vector<std::string> getOutput(void) = 0;
|
||||||
// parse parameters
|
// parse parameters
|
||||||
virtual void parseParameters(XmlReader &reader, const std::string name) = 0;
|
virtual void parseParameters(XmlReader &reader, const std::string name) = 0;
|
||||||
virtual void saveParameters(XmlWriter &writer, const std::string name) = 0;
|
virtual void saveParameters(XmlWriter &writer, const std::string name) = 0;
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void) {};
|
virtual void setup(void) {};
|
||||||
|
virtual void execute(void) = 0;
|
||||||
// execution
|
// execution
|
||||||
void operator()(void);
|
void operator()(void);
|
||||||
virtual void execute(void) = 0;
|
protected:
|
||||||
|
// environment shortcut
|
||||||
|
DEFINE_ENV_ALIAS;
|
||||||
|
// virtual machine shortcut
|
||||||
|
DEFINE_VM_ALIAS;
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
Environment &env_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// derived class, templating the parameter class
|
// derived class, templating the parameter class
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/ModuleFactory.hpp
|
Source file: extras/Hadrons/ModuleFactory.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
|
@ -1,25 +1,65 @@
|
|||||||
#include <Grid/Hadrons/Modules/MAction/DWF.hpp>
|
/*************************************************************************************
|
||||||
#include <Grid/Hadrons/Modules/MAction/Wilson.hpp>
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
#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/Meson.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.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/DiscLoop.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/MContraction/WardIdentity.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MFermion/GaugeProp.hpp>
|
#include <Grid/Hadrons/Modules/MFermion/GaugeProp.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/StochEm.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MLoop/NoiseLoop.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MScalar/ChargedProp.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MScalar/FreeProp.hpp>
|
|
||||||
#include <Grid/Hadrons/Modules/MScalar/Scalar.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/SeqGamma.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/Point.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/Wall.hpp>
|
#include <Grid/Hadrons/Modules/MSource/Wall.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MSource/Z2.hpp>
|
#include <Grid/Hadrons/Modules/MSource/Z2.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/SeqConserved.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSink/Smear.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSink/Point.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/StochEm.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/FundtoHirep.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MUtilities/TestSeqGamma.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MUtilities/TestSeqConserved.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MLoop/NoiseLoop.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalar/FreeProp.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalar/Scalar.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalar/ChargedProp.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MAction/DWF.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MAction/Wilson.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MAction/WilsonClover.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalarSUN/Div.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalarSUN/TrMag.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalarSUN/TwoPoint.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MScalarSUN/TrPhi.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MIO/LoadNersc.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MIO/LoadBinary.hpp>
|
||||||
|
@ -4,10 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MAction/DWF.hpp
|
Source file: extras/Hadrons/Modules/MAction/DWF.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -65,6 +65,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -102,16 +103,6 @@ std::vector<std::string> TDWF<FImpl>::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TDWF<FImpl>::setup(void)
|
void TDWF<FImpl>::setup(void)
|
||||||
{
|
|
||||||
unsigned int size;
|
|
||||||
|
|
||||||
size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
|
|
||||||
env().registerObject(getName(), size, par().Ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
|
||||||
template <typename FImpl>
|
|
||||||
void TDWF<FImpl>::execute(void)
|
|
||||||
{
|
{
|
||||||
LOG(Message) << "Setting up domain wall fermion matrix with m= "
|
LOG(Message) << "Setting up domain wall fermion matrix with m= "
|
||||||
<< par().mass << ", M5= " << par().M5 << " and Ls= "
|
<< par().mass << ", M5= " << par().M5 << " and Ls= "
|
||||||
@ -119,20 +110,24 @@ void TDWF<FImpl>::execute(void)
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
LOG(Message) << "Fermion boundary conditions: " << par().boundary
|
LOG(Message) << "Fermion boundary conditions: " << par().boundary
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
env().createGrid(par().Ls);
|
env().createGrid(par().Ls);
|
||||||
auto &U = *env().template getObject<LatticeGaugeField>(par().gauge);
|
auto &U = envGet(LatticeGaugeField, par().gauge);
|
||||||
auto &g4 = *env().getGrid();
|
auto &g4 = *env().getGrid();
|
||||||
auto &grb4 = *env().getRbGrid();
|
auto &grb4 = *env().getRbGrid();
|
||||||
auto &g5 = *env().getGrid(par().Ls);
|
auto &g5 = *env().getGrid(par().Ls);
|
||||||
auto &grb5 = *env().getRbGrid(par().Ls);
|
auto &grb5 = *env().getRbGrid(par().Ls);
|
||||||
std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
|
std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
|
||||||
typename DomainWallFermion<FImpl>::ImplParams implParams(boundary);
|
typename DomainWallFermion<FImpl>::ImplParams implParams(boundary);
|
||||||
FMat *fMatPt = new DomainWallFermion<FImpl>(U, g5, grb5, g4, grb4,
|
envCreateDerived(FMat, DomainWallFermion<FImpl>, getName(), par().Ls, U, g5,
|
||||||
par().mass, par().M5,
|
grb5, g4, grb4, par().mass, par().M5, implParams);
|
||||||
implParams);
|
|
||||||
env().setObject(getName(), fMatPt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TDWF<FImpl>::execute(void)
|
||||||
|
{}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
@ -4,10 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MAction/Wilson.hpp
|
Source file: extras/Hadrons/Modules/MAction/Wilson.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -63,6 +63,7 @@ public:
|
|||||||
// dependencies/products
|
// dependencies/products
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -101,29 +102,24 @@ std::vector<std::string> TWilson<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TWilson<FImpl>::setup(void)
|
void TWilson<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
LOG(Message) << "Setting up TWilson fermion matrix with m= " << par().mass
|
||||||
|
<< " using gauge field '" << par().gauge << "'" << std::endl;
|
||||||
|
LOG(Message) << "Fermion boundary conditions: " << par().boundary
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
|
auto &U = envGet(LatticeGaugeField, par().gauge);
|
||||||
env().registerObject(getName(), size);
|
auto &grid = *env().getGrid();
|
||||||
|
auto &gridRb = *env().getRbGrid();
|
||||||
|
std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
|
||||||
|
typename WilsonFermion<FImpl>::ImplParams implParams(boundary);
|
||||||
|
envCreateDerived(FMat, WilsonFermion<FImpl>, getName(), 1, U, grid, gridRb,
|
||||||
|
par().mass, implParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TWilson<FImpl>::execute()
|
void TWilson<FImpl>::execute()
|
||||||
{
|
{}
|
||||||
LOG(Message) << "Setting up TWilson fermion matrix with m= " << par().mass
|
|
||||||
<< " using gauge field '" << par().gauge << "'" << std::endl;
|
|
||||||
LOG(Message) << "Fermion boundary conditions: " << par().boundary
|
|
||||||
<< std::endl;
|
|
||||||
auto &U = *env().template getObject<LatticeGaugeField>(par().gauge);
|
|
||||||
auto &grid = *env().getGrid();
|
|
||||||
auto &gridRb = *env().getRbGrid();
|
|
||||||
std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
|
|
||||||
typename WilsonFermion<FImpl>::ImplParams implParams(boundary);
|
|
||||||
FMat *fMatPt = new WilsonFermion<FImpl>(U, grid, gridRb, par().mass,
|
|
||||||
implParams);
|
|
||||||
env().setObject(getName(), fMatPt);
|
|
||||||
}
|
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
153
extras/Hadrons/Modules/MAction/WilsonClover.hpp
Normal file
153
extras/Hadrons/Modules/MAction/WilsonClover.hpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MAction/Wilson.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_MAction_WilsonClover_hpp_
|
||||||
|
#define Hadrons_MAction_WilsonClover_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TWilson quark action *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MAction)
|
||||||
|
|
||||||
|
class WilsonCloverPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(WilsonCloverPar,
|
||||||
|
std::string, gauge,
|
||||||
|
double , mass,
|
||||||
|
double , csw_r,
|
||||||
|
double , csw_t,
|
||||||
|
WilsonAnisotropyCoefficients ,clover_anisotropy,
|
||||||
|
std::string, boundary
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TWilsonClover: public Module<WilsonCloverPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FGS_TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TWilsonClover(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TWilsonClover(void) = default;
|
||||||
|
// dependencies/products
|
||||||
|
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(WilsonClover, TWilsonClover<FIMPL>, MAction);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TWilsonClover template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TWilsonClover<FImpl>::TWilsonClover(const std::string name)
|
||||||
|
: Module<WilsonCloverPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TWilsonClover<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().gauge};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TWilsonClover<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TWilsonClover<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
//unsigned int size;
|
||||||
|
|
||||||
|
// size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
|
||||||
|
// env().registerObject(getName(), size);
|
||||||
|
|
||||||
|
|
||||||
|
LOG(Message) << "Setting up TWilsonClover fermion matrix with m= " << par().mass
|
||||||
|
<< " using gauge field '" << par().gauge << "'" << std::endl;
|
||||||
|
LOG(Message) << "Fermion boundary conditions: " << par().boundary
|
||||||
|
<< std::endl;
|
||||||
|
LOG(Message) << "Clover term csw_r: " << par().csw_r
|
||||||
|
<< " csw_t: " << par().csw_t
|
||||||
|
<< std::endl;
|
||||||
|
auto &U = envGet(LatticeGaugeField, par().gauge);
|
||||||
|
auto &grid = *env().getGrid();
|
||||||
|
auto &gridRb = *env().getRbGrid();
|
||||||
|
std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
|
||||||
|
typename WilsonCloverFermion<FImpl>::ImplParams implParams(boundary);
|
||||||
|
envCreateDerived(FMat, WilsonCloverFermion<FImpl>, getName(), 1, U, grid, gridRb, par().mass,
|
||||||
|
par().csw_r,
|
||||||
|
par().csw_t,
|
||||||
|
par().clover_anisotropy,
|
||||||
|
implParams);
|
||||||
|
|
||||||
|
|
||||||
|
//FMat *fMatPt = new WilsonCloverFermion<FImpl>(U, grid, gridRb, par().mass,
|
||||||
|
// par().csw_r,
|
||||||
|
// par().csw_t,
|
||||||
|
// par().clover_anisotropy,
|
||||||
|
// implParams);
|
||||||
|
//env().setObject(getName(), fMatPt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TWilsonClover<FImpl>::execute()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_WilsonClover_hpp_
|
@ -4,10 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/Baryon.hpp
|
Source file: extras/Hadrons/Modules/MContraction/Baryon.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -72,6 +72,9 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
};
|
};
|
||||||
@ -99,11 +102,18 @@ std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getInput(void)
|
|||||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getOutput(void)
|
std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
|
void TBaryon<FImpl1, FImpl2, FImpl3>::setup(void)
|
||||||
|
{
|
||||||
|
envTmpLat(LatticeComplex, "c");
|
||||||
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
void TBaryon<FImpl1, FImpl2, FImpl3>::execute(void)
|
void TBaryon<FImpl1, FImpl2, FImpl3>::execute(void)
|
||||||
@ -112,12 +122,12 @@ void TBaryon<FImpl1, FImpl2, FImpl3>::execute(void)
|
|||||||
<< " quarks '" << par().q1 << "', '" << par().q2 << "', and '"
|
<< " quarks '" << par().q1 << "', '" << par().q2 << "', and '"
|
||||||
<< par().q3 << "'" << std::endl;
|
<< par().q3 << "'" << std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
PropagatorField1 &q1 = *env().template getObject<PropagatorField1>(par().q1);
|
auto &q1 = envGet(PropagatorField1, par().q1);
|
||||||
PropagatorField2 &q2 = *env().template getObject<PropagatorField2>(par().q2);
|
auto &q2 = envGet(PropagatorField2, par().q2);
|
||||||
PropagatorField3 &q3 = *env().template getObject<PropagatorField3>(par().q2);
|
auto &q3 = envGet(PropagatorField3, par().q2);
|
||||||
LatticeComplex c(env().getGrid());
|
envGetTmp(LatticeComplex, c);
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
// FIXME: do contractions
|
// FIXME: do contractions
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/DiscLoop.hpp
|
Source file: extras/Hadrons/Modules/MContraction/DiscLoop.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -68,6 +69,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -97,7 +99,7 @@ std::vector<std::string> TDiscLoop<FImpl>::getInput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TDiscLoop<FImpl>::getOutput(void)
|
std::vector<std::string> TDiscLoop<FImpl>::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -106,7 +108,7 @@ std::vector<std::string> TDiscLoop<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TDiscLoop<FImpl>::setup(void)
|
void TDiscLoop<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
|
envTmpLat(LatticeComplex, "c");
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -117,13 +119,13 @@ void TDiscLoop<FImpl>::execute(void)
|
|||||||
<< "' using '" << par().q_loop << "' with " << par().gamma
|
<< "' using '" << par().q_loop << "' with " << par().gamma
|
||||||
<< " insertion." << std::endl;
|
<< " insertion." << std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
PropagatorField &q_loop = *env().template getObject<PropagatorField>(par().q_loop);
|
auto &q_loop = envGet(PropagatorField, par().q_loop);
|
||||||
LatticeComplex c(env().getGrid());
|
|
||||||
Gamma gamma(par().gamma);
|
Gamma gamma(par().gamma);
|
||||||
std::vector<TComplex> buf;
|
std::vector<TComplex> buf;
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
|
envGetTmp(LatticeComplex, c);
|
||||||
c = trace(gamma*q_loop);
|
c = trace(gamma*q_loop);
|
||||||
sliceSum(c, buf, Tp);
|
sliceSum(c, buf, Tp);
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/Gamma3pt.hpp
|
Source file: extras/Hadrons/Modules/MContraction/Gamma3pt.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -51,6 +52,14 @@ BEGIN_HADRONS_NAMESPACE
|
|||||||
* q1
|
* q1
|
||||||
*
|
*
|
||||||
* trace(g5*q1*adj(q2)*g5*gamma*q3)
|
* trace(g5*q1*adj(q2)*g5*gamma*q3)
|
||||||
|
*
|
||||||
|
* options:
|
||||||
|
* - q1: sink smeared propagator, source at i
|
||||||
|
* - q2: propagator, source at i
|
||||||
|
* - q3: propagator, source at f
|
||||||
|
* - gamma: gamma matrix to insert
|
||||||
|
* - tSnk: sink position for propagator q1.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -66,6 +75,7 @@ public:
|
|||||||
std::string, q2,
|
std::string, q2,
|
||||||
std::string, q3,
|
std::string, q3,
|
||||||
Gamma::Algebra, gamma,
|
Gamma::Algebra, gamma,
|
||||||
|
unsigned int, tSnk,
|
||||||
std::string, output);
|
std::string, output);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,6 +100,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -119,7 +130,7 @@ std::vector<std::string> TGamma3pt<FImpl1, FImpl2, FImpl3>::getInput(void)
|
|||||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
std::vector<std::string> TGamma3pt<FImpl1, FImpl2, FImpl3>::getOutput(void)
|
std::vector<std::string> TGamma3pt<FImpl1, FImpl2, FImpl3>::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -128,7 +139,7 @@ std::vector<std::string> TGamma3pt<FImpl1, FImpl2, FImpl3>::getOutput(void)
|
|||||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
void TGamma3pt<FImpl1, FImpl2, FImpl3>::setup(void)
|
void TGamma3pt<FImpl1, FImpl2, FImpl3>::setup(void)
|
||||||
{
|
{
|
||||||
|
envTmpLat(LatticeComplex, "c");
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -140,17 +151,22 @@ void TGamma3pt<FImpl1, FImpl2, FImpl3>::execute(void)
|
|||||||
<< par().q3 << "', with " << par().gamma << " insertion."
|
<< par().q3 << "', with " << par().gamma << " insertion."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
// Initialise variables. q2 and q3 are normal propagators, q1 may be
|
||||||
PropagatorField1 &q1 = *env().template getObject<PropagatorField1>(par().q1);
|
// sink smeared.
|
||||||
PropagatorField2 &q2 = *env().template getObject<PropagatorField2>(par().q2);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
PropagatorField3 &q3 = *env().template getObject<PropagatorField3>(par().q3);
|
auto &q1 = envGet(SlicedPropagator1, par().q1);
|
||||||
LatticeComplex c(env().getGrid());
|
auto &q2 = envGet(PropagatorField2, par().q2);
|
||||||
|
auto &q3 = envGet(PropagatorField2, par().q3);
|
||||||
Gamma g5(Gamma::Algebra::Gamma5);
|
Gamma g5(Gamma::Algebra::Gamma5);
|
||||||
Gamma gamma(par().gamma);
|
Gamma gamma(par().gamma);
|
||||||
std::vector<TComplex> buf;
|
std::vector<TComplex> buf;
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
c = trace(g5*q1*adj(q2)*(g5*gamma)*q3);
|
// Extract relevant timeslice of sinked propagator q1, then contract &
|
||||||
|
// sum over all spacial positions of gamma insertion.
|
||||||
|
SitePropagator1 q1Snk = q1[par().tSnk];
|
||||||
|
envGetTmp(LatticeComplex, c);
|
||||||
|
c = trace(g5*q1Snk*adj(q2)*(g5*gamma)*q3);
|
||||||
sliceSum(c, buf, Tp);
|
sliceSum(c, buf, Tp);
|
||||||
|
|
||||||
result.gamma = par().gamma;
|
result.gamma = par().gamma;
|
||||||
|
@ -4,12 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/Meson.hpp
|
Source file: extras/Hadrons/Modules/MContraction/Meson.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -51,8 +49,7 @@ BEGIN_HADRONS_NAMESPACE
|
|||||||
in a sequence (e.g. "<Gamma5 Gamma5><Gamma5 GammaT>").
|
in a sequence (e.g. "<Gamma5 Gamma5><Gamma5 GammaT>").
|
||||||
|
|
||||||
Special values: "all" - perform all possible contractions.
|
Special values: "all" - perform all possible contractions.
|
||||||
- mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0."),
|
- sink: module to compute the sink to use in contraction (string).
|
||||||
given as multiples of (2*pi) / L.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -98,6 +95,9 @@ public:
|
|||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
virtual void parseGammaString(std::vector<GammaPair> &gammaList);
|
virtual void parseGammaString(std::vector<GammaPair> &gammaList);
|
||||||
|
protected:
|
||||||
|
// execution
|
||||||
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
};
|
};
|
||||||
@ -125,7 +125,7 @@ std::vector<std::string> TMeson<FImpl1, FImpl2>::getInput(void)
|
|||||||
template <typename FImpl1, typename FImpl2>
|
template <typename FImpl1, typename FImpl2>
|
||||||
std::vector<std::string> TMeson<FImpl1, FImpl2>::getOutput(void)
|
std::vector<std::string> TMeson<FImpl1, FImpl2>::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> output = {getName()};
|
std::vector<std::string> output = {};
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@ -154,6 +154,12 @@ void TMeson<FImpl1, FImpl2>::parseGammaString(std::vector<GammaPair> &gammaList)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2>
|
||||||
|
void TMeson<FImpl1, FImpl2>::setup(void)
|
||||||
|
{
|
||||||
|
envTmpLat(LatticeComplex, "c");
|
||||||
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
#define mesonConnected(q1, q2, gSnk, gSrc) \
|
#define mesonConnected(q1, q2, gSnk, gSrc) \
|
||||||
@ -166,7 +172,7 @@ void TMeson<FImpl1, FImpl2>::execute(void)
|
|||||||
<< " quarks '" << par().q1 << "' and '" << par().q2 << "'"
|
<< " quarks '" << par().q1 << "' and '" << par().q2 << "'"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
std::vector<TComplex> buf;
|
std::vector<TComplex> buf;
|
||||||
std::vector<Result> result;
|
std::vector<Result> result;
|
||||||
Gamma g5(Gamma::Algebra::Gamma5);
|
Gamma g5(Gamma::Algebra::Gamma5);
|
||||||
@ -181,11 +187,11 @@ void TMeson<FImpl1, FImpl2>::execute(void)
|
|||||||
result[i].gamma_src = gammaList[i].second;
|
result[i].gamma_src = gammaList[i].second;
|
||||||
result[i].corr.resize(nt);
|
result[i].corr.resize(nt);
|
||||||
}
|
}
|
||||||
if (env().template isObjectOfType<SlicedPropagator1>(par().q1) and
|
if (envHasType(SlicedPropagator1, par().q1) and
|
||||||
env().template isObjectOfType<SlicedPropagator2>(par().q2))
|
envHasType(SlicedPropagator2, par().q2))
|
||||||
{
|
{
|
||||||
SlicedPropagator1 &q1 = *env().template getObject<SlicedPropagator1>(par().q1);
|
auto &q1 = envGet(SlicedPropagator1, par().q1);
|
||||||
SlicedPropagator2 &q2 = *env().template getObject<SlicedPropagator2>(par().q2);
|
auto &q2 = envGet(SlicedPropagator2, par().q2);
|
||||||
|
|
||||||
LOG(Message) << "(propagator already sinked)" << std::endl;
|
LOG(Message) << "(propagator already sinked)" << std::endl;
|
||||||
for (unsigned int i = 0; i < result.size(); ++i)
|
for (unsigned int i = 0; i < result.size(); ++i)
|
||||||
@ -201,10 +207,10 @@ void TMeson<FImpl1, FImpl2>::execute(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PropagatorField1 &q1 = *env().template getObject<PropagatorField1>(par().q1);
|
auto &q1 = envGet(PropagatorField1, par().q1);
|
||||||
PropagatorField2 &q2 = *env().template getObject<PropagatorField2>(par().q2);
|
auto &q2 = envGet(PropagatorField2, par().q2);
|
||||||
LatticeComplex c(env().getGrid());
|
|
||||||
|
|
||||||
|
envGetTmp(LatticeComplex, c);
|
||||||
LOG(Message) << "(using sink '" << par().sink << "')" << std::endl;
|
LOG(Message) << "(using sink '" << par().sink << "')" << std::endl;
|
||||||
for (unsigned int i = 0; i < result.size(); ++i)
|
for (unsigned int i = 0; i < result.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -212,18 +218,17 @@ void TMeson<FImpl1, FImpl2>::execute(void)
|
|||||||
Gamma gSrc(gammaList[i].second);
|
Gamma gSrc(gammaList[i].second);
|
||||||
std::string ns;
|
std::string ns;
|
||||||
|
|
||||||
ns = env().getModuleNamespace(env().getObjectModule(par().sink));
|
ns = vm().getModuleNamespace(env().getObjectModule(par().sink));
|
||||||
if (ns == "MSource")
|
if (ns == "MSource")
|
||||||
{
|
{
|
||||||
PropagatorField1 &sink =
|
PropagatorField1 &sink = envGet(PropagatorField1, par().sink);
|
||||||
*env().template getObject<PropagatorField1>(par().sink);
|
|
||||||
|
|
||||||
c = trace(mesonConnected(q1, q2, gSnk, gSrc)*sink);
|
c = trace(mesonConnected(q1, q2, gSnk, gSrc)*sink);
|
||||||
sliceSum(c, buf, Tp);
|
sliceSum(c, buf, Tp);
|
||||||
}
|
}
|
||||||
else if (ns == "MSink")
|
else if (ns == "MSink")
|
||||||
{
|
{
|
||||||
SinkFnScalar &sink = *env().template getObject<SinkFnScalar>(par().sink);
|
SinkFnScalar &sink = envGet(SinkFnScalar, par().sink);
|
||||||
|
|
||||||
c = trace(mesonConnected(q1, q2, gSnk, gSrc));
|
c = trace(mesonConnected(q1, q2, gSnk, gSrc));
|
||||||
buf = sink(c);
|
buf = sink(c);
|
||||||
|
224
extras/Hadrons/Modules/MContraction/WardIdentity.hpp
Normal file
224
extras/Hadrons/Modules/MContraction/WardIdentity.hpp
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MContraction/WardIdentity.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_MContraction_WardIdentity_hpp_
|
||||||
|
#define Hadrons_MContraction_WardIdentity_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ward Identity contractions
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
* options:
|
||||||
|
- q: propagator, 5D if available (string)
|
||||||
|
- action: action module used for propagator solution (string)
|
||||||
|
- mass: mass of quark (double)
|
||||||
|
- test_axial: whether or not to test PCAC relation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* WardIdentity *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||||
|
|
||||||
|
class WardIdentityPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(WardIdentityPar,
|
||||||
|
std::string, q,
|
||||||
|
std::string, action,
|
||||||
|
double, mass,
|
||||||
|
bool, test_axial);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TWardIdentity: public Module<WardIdentityPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FERM_TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TWardIdentity(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TWardIdentity(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
private:
|
||||||
|
unsigned int Ls_;
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(WardIdentity, TWardIdentity<FIMPL>, MContraction);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TWardIdentity implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TWardIdentity<FImpl>::TWardIdentity(const std::string name)
|
||||||
|
: Module<WardIdentityPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TWardIdentity<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().q, par().action};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TWardIdentity<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TWardIdentity<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
Ls_ = env().getObjectLs(par().q);
|
||||||
|
if (Ls_ != env().getObjectLs(par().action))
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Size, "Ls mismatch between quark action and propagator");
|
||||||
|
}
|
||||||
|
envTmpLat(PropagatorField, "tmp");
|
||||||
|
envTmpLat(PropagatorField, "vector_WI");
|
||||||
|
if (par().test_axial)
|
||||||
|
{
|
||||||
|
envTmpLat(PropagatorField, "psi");
|
||||||
|
envTmpLat(LatticeComplex, "PP");
|
||||||
|
envTmpLat(LatticeComplex, "axial_defect");
|
||||||
|
envTmpLat(LatticeComplex, "PJ5q");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TWardIdentity<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Performing Ward Identity checks for quark '" << par().q
|
||||||
|
<< "'." << std::endl;
|
||||||
|
|
||||||
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
|
auto &act = envGet(FMat, par().action);
|
||||||
|
Gamma g5(Gamma::Algebra::Gamma5);
|
||||||
|
|
||||||
|
// Compute D_mu V_mu, D here is backward derivative.
|
||||||
|
envGetTmp(PropagatorField, tmp);
|
||||||
|
envGetTmp(PropagatorField, vector_WI);
|
||||||
|
vector_WI = zero;
|
||||||
|
for (unsigned int mu = 0; mu < Nd; ++mu)
|
||||||
|
{
|
||||||
|
act.ContractConservedCurrent(q, q, tmp, Current::Vector, mu);
|
||||||
|
tmp -= Cshift(tmp, mu, -1);
|
||||||
|
vector_WI += tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test ward identity D_mu V_mu = 0;
|
||||||
|
LOG(Message) << "Vector Ward Identity check Delta_mu V_mu = "
|
||||||
|
<< norm2(vector_WI) << std::endl;
|
||||||
|
|
||||||
|
if (par().test_axial)
|
||||||
|
{
|
||||||
|
envGetTmp(PropagatorField, psi);
|
||||||
|
envGetTmp(LatticeComplex, PP);
|
||||||
|
envGetTmp(LatticeComplex, axial_defect);
|
||||||
|
envGetTmp(LatticeComplex, PJ5q);
|
||||||
|
std::vector<TComplex> axial_buf;
|
||||||
|
|
||||||
|
// Compute <P|D_mu A_mu>, D is backwards derivative.
|
||||||
|
axial_defect = zero;
|
||||||
|
for (unsigned int mu = 0; mu < Nd; ++mu)
|
||||||
|
{
|
||||||
|
act.ContractConservedCurrent(q, q, tmp, Current::Axial, mu);
|
||||||
|
tmp -= Cshift(tmp, mu, -1);
|
||||||
|
axial_defect += trace(g5*tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get <P|J5q> for 5D (zero for 4D) and <P|P>.
|
||||||
|
PJ5q = zero;
|
||||||
|
if (Ls_ > 1)
|
||||||
|
{
|
||||||
|
// <P|P>
|
||||||
|
ExtractSlice(tmp, q, 0, 0);
|
||||||
|
psi = 0.5 * (tmp - g5*tmp);
|
||||||
|
ExtractSlice(tmp, q, Ls_ - 1, 0);
|
||||||
|
psi += 0.5 * (tmp + g5*tmp);
|
||||||
|
PP = trace(adj(psi)*psi);
|
||||||
|
|
||||||
|
// <P|5Jq>
|
||||||
|
ExtractSlice(tmp, q, Ls_/2 - 1, 0);
|
||||||
|
psi = 0.5 * (tmp + g5*tmp);
|
||||||
|
ExtractSlice(tmp, q, Ls_/2, 0);
|
||||||
|
psi += 0.5 * (tmp - g5*tmp);
|
||||||
|
PJ5q = trace(adj(psi)*psi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PP = trace(adj(q)*q);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test ward identity <P|D_mu A_mu> = 2m<P|P> + 2<P|J5q>
|
||||||
|
LOG(Message) << "|D_mu A_mu|^2 = " << norm2(axial_defect) << std::endl;
|
||||||
|
LOG(Message) << "|PP|^2 = " << norm2(PP) << std::endl;
|
||||||
|
LOG(Message) << "|PJ5q|^2 = " << norm2(PJ5q) << std::endl;
|
||||||
|
LOG(Message) << "Axial Ward Identity defect Delta_mu A_mu = "
|
||||||
|
<< norm2(axial_defect) << std::endl;
|
||||||
|
|
||||||
|
// Axial defect by timeslice.
|
||||||
|
axial_defect -= 2.*(par().mass*PP + PJ5q);
|
||||||
|
LOG(Message) << "Check Axial defect by timeslice" << std::endl;
|
||||||
|
sliceSum(axial_defect, axial_buf, Tp);
|
||||||
|
for (int t = 0; t < axial_buf.size(); ++t)
|
||||||
|
{
|
||||||
|
LOG(Message) << "t = " << t << ": "
|
||||||
|
<< TensorRemove(axial_buf[t]) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_WardIdentity_hpp_
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp
|
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -76,6 +77,7 @@ public:
|
|||||||
std::string, q2,
|
std::string, q2,
|
||||||
std::string, q3,
|
std::string, q3,
|
||||||
std::string, q4,
|
std::string, q4,
|
||||||
|
unsigned int, tSnk,
|
||||||
std::string, output);
|
std::string, output);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,11 +101,13 @@ public:\
|
|||||||
/* dependency relation */ \
|
/* dependency relation */ \
|
||||||
virtual std::vector<std::string> getInput(void);\
|
virtual std::vector<std::string> getInput(void);\
|
||||||
virtual std::vector<std::string> getOutput(void);\
|
virtual std::vector<std::string> getOutput(void);\
|
||||||
|
public:\
|
||||||
|
std::vector<std::string> VA_label = {"V", "A"};\
|
||||||
|
protected:\
|
||||||
/* setup */ \
|
/* setup */ \
|
||||||
virtual void setup(void);\
|
virtual void setup(void);\
|
||||||
/* execution */ \
|
/* execution */ \
|
||||||
virtual void execute(void);\
|
virtual void execute(void);\
|
||||||
std::vector<std::string> VA_label = {"V", "A"};\
|
|
||||||
};\
|
};\
|
||||||
MODULE_REGISTER_NS(modname, T##modname, MContraction);
|
MODULE_REGISTER_NS(modname, T##modname, MContraction);
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.cc
|
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.cc
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -54,6 +55,8 @@ using namespace MContraction;
|
|||||||
*
|
*
|
||||||
* S: trace(q3*g5*q1*adj(q2)*g5*gL[mu][p_1]*q4*gL[mu][p_2])
|
* S: trace(q3*g5*q1*adj(q2)*g5*gL[mu][p_1]*q4*gL[mu][p_2])
|
||||||
* E: trace(q3*g5*q1*adj(q2)*g5*gL[mu][p_1])*trace(q4*gL[mu][p_2])
|
* E: trace(q3*g5*q1*adj(q2)*g5*gL[mu][p_1])*trace(q4*gL[mu][p_2])
|
||||||
|
*
|
||||||
|
* Note q1 must be sink smeared.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -74,7 +77,7 @@ std::vector<std::string> TWeakHamiltonianEye::getInput(void)
|
|||||||
|
|
||||||
std::vector<std::string> TWeakHamiltonianEye::getOutput(void)
|
std::vector<std::string> TWeakHamiltonianEye::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -82,7 +85,15 @@ std::vector<std::string> TWeakHamiltonianEye::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TWeakHamiltonianEye::setup(void)
|
void TWeakHamiltonianEye::setup(void)
|
||||||
{
|
{
|
||||||
|
unsigned int ndim = env().getNd();
|
||||||
|
|
||||||
|
envTmpLat(LatticeComplex, "expbuf");
|
||||||
|
envTmpLat(PropagatorField, "tmp1");
|
||||||
|
envTmpLat(LatticeComplex, "tmp2");
|
||||||
|
envTmp(std::vector<PropagatorField>, "S_body", 1, ndim, PropagatorField(env().getGrid()));
|
||||||
|
envTmp(std::vector<PropagatorField>, "S_loop", 1, ndim, PropagatorField(env().getGrid()));
|
||||||
|
envTmp(std::vector<LatticeComplex>, "E_body", 1, ndim, LatticeComplex(env().getGrid()));
|
||||||
|
envTmp(std::vector<LatticeComplex>, "E_loop", 1, ndim, LatticeComplex(env().getGrid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -93,28 +104,31 @@ void TWeakHamiltonianEye::execute(void)
|
|||||||
<< par().q2 << ", '" << par().q3 << "' and '" << par().q4
|
<< par().q2 << ", '" << par().q3 << "' and '" << par().q4
|
||||||
<< "'." << std::endl;
|
<< "'." << std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
PropagatorField &q1 = *env().template getObject<PropagatorField>(par().q1);
|
auto &q1 = envGet(SlicedPropagator, par().q1);
|
||||||
PropagatorField &q2 = *env().template getObject<PropagatorField>(par().q2);
|
auto &q2 = envGet(PropagatorField, par().q2);
|
||||||
PropagatorField &q3 = *env().template getObject<PropagatorField>(par().q3);
|
auto &q3 = envGet(PropagatorField, par().q3);
|
||||||
PropagatorField &q4 = *env().template getObject<PropagatorField>(par().q4);
|
auto &q4 = envGet(PropagatorField, par().q4);
|
||||||
Gamma g5 = Gamma(Gamma::Algebra::Gamma5);
|
Gamma g5 = Gamma(Gamma::Algebra::Gamma5);
|
||||||
LatticeComplex expbuf(env().getGrid());
|
std::vector<TComplex> corrbuf;
|
||||||
std::vector<TComplex> corrbuf;
|
std::vector<Result> result(n_eye_diag);
|
||||||
std::vector<Result> result(n_eye_diag);
|
unsigned int ndim = env().getNd();
|
||||||
unsigned int ndim = env().getNd();
|
|
||||||
|
|
||||||
PropagatorField tmp1(env().getGrid());
|
envGetTmp(LatticeComplex, expbuf);
|
||||||
LatticeComplex tmp2(env().getGrid());
|
envGetTmp(PropagatorField, tmp1);
|
||||||
std::vector<PropagatorField> S_body(ndim, tmp1);
|
envGetTmp(LatticeComplex, tmp2);
|
||||||
std::vector<PropagatorField> S_loop(ndim, tmp1);
|
envGetTmp(std::vector<PropagatorField>, S_body);
|
||||||
std::vector<LatticeComplex> E_body(ndim, tmp2);
|
envGetTmp(std::vector<PropagatorField>, S_loop);
|
||||||
std::vector<LatticeComplex> E_loop(ndim, tmp2);
|
envGetTmp(std::vector<LatticeComplex>, E_body);
|
||||||
|
envGetTmp(std::vector<LatticeComplex>, E_loop);
|
||||||
|
|
||||||
|
// Get sink timeslice of q1.
|
||||||
|
SitePropagator q1Snk = q1[par().tSnk];
|
||||||
|
|
||||||
// Setup for S-type contractions.
|
// Setup for S-type contractions.
|
||||||
for (int mu = 0; mu < ndim; ++mu)
|
for (int mu = 0; mu < ndim; ++mu)
|
||||||
{
|
{
|
||||||
S_body[mu] = MAKE_SE_BODY(q1, q2, q3, GammaL(Gamma::gmu[mu]));
|
S_body[mu] = MAKE_SE_BODY(q1Snk, q2, q3, GammaL(Gamma::gmu[mu]));
|
||||||
S_loop[mu] = MAKE_SE_LOOP(q4, GammaL(Gamma::gmu[mu]));
|
S_loop[mu] = MAKE_SE_LOOP(q4, GammaL(Gamma::gmu[mu]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp
|
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.cc
|
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.cc
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -76,7 +77,7 @@ std::vector<std::string> TWeakHamiltonianNonEye::getInput(void)
|
|||||||
|
|
||||||
std::vector<std::string> TWeakHamiltonianNonEye::getOutput(void)
|
std::vector<std::string> TWeakHamiltonianNonEye::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -84,7 +85,15 @@ std::vector<std::string> TWeakHamiltonianNonEye::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TWeakHamiltonianNonEye::setup(void)
|
void TWeakHamiltonianNonEye::setup(void)
|
||||||
{
|
{
|
||||||
|
unsigned int ndim = env().getNd();
|
||||||
|
|
||||||
|
envTmpLat(LatticeComplex, "expbuf");
|
||||||
|
envTmpLat(PropagatorField, "tmp1");
|
||||||
|
envTmpLat(LatticeComplex, "tmp2");
|
||||||
|
envTmp(std::vector<PropagatorField>, "C_i_side_loop", 1, ndim, PropagatorField(env().getGrid()));
|
||||||
|
envTmp(std::vector<PropagatorField>, "C_f_side_loop", 1, ndim, PropagatorField(env().getGrid()));
|
||||||
|
envTmp(std::vector<LatticeComplex>, "W_i_side_loop", 1, ndim, LatticeComplex(env().getGrid()));
|
||||||
|
envTmp(std::vector<LatticeComplex>, "W_f_side_loop", 1, ndim, LatticeComplex(env().getGrid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -95,23 +104,23 @@ void TWeakHamiltonianNonEye::execute(void)
|
|||||||
<< par().q2 << ", '" << par().q3 << "' and '" << par().q4
|
<< par().q2 << ", '" << par().q3 << "' and '" << par().q4
|
||||||
<< "'." << std::endl;
|
<< "'." << std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
PropagatorField &q1 = *env().template getObject<PropagatorField>(par().q1);
|
auto &q1 = envGet(PropagatorField, par().q1);
|
||||||
PropagatorField &q2 = *env().template getObject<PropagatorField>(par().q2);
|
auto &q2 = envGet(PropagatorField, par().q2);
|
||||||
PropagatorField &q3 = *env().template getObject<PropagatorField>(par().q3);
|
auto &q3 = envGet(PropagatorField, par().q3);
|
||||||
PropagatorField &q4 = *env().template getObject<PropagatorField>(par().q4);
|
auto &q4 = envGet(PropagatorField, par().q4);
|
||||||
Gamma g5 = Gamma(Gamma::Algebra::Gamma5);
|
Gamma g5 = Gamma(Gamma::Algebra::Gamma5);
|
||||||
LatticeComplex expbuf(env().getGrid());
|
|
||||||
std::vector<TComplex> corrbuf;
|
std::vector<TComplex> corrbuf;
|
||||||
std::vector<Result> result(n_noneye_diag);
|
std::vector<Result> result(n_noneye_diag);
|
||||||
unsigned int ndim = env().getNd();
|
unsigned int ndim = env().getNd();
|
||||||
|
|
||||||
PropagatorField tmp1(env().getGrid());
|
envGetTmp(LatticeComplex, expbuf);
|
||||||
LatticeComplex tmp2(env().getGrid());
|
envGetTmp(PropagatorField, tmp1);
|
||||||
std::vector<PropagatorField> C_i_side_loop(ndim, tmp1);
|
envGetTmp(LatticeComplex, tmp2);
|
||||||
std::vector<PropagatorField> C_f_side_loop(ndim, tmp1);
|
envGetTmp(std::vector<PropagatorField>, C_i_side_loop);
|
||||||
std::vector<LatticeComplex> W_i_side_loop(ndim, tmp2);
|
envGetTmp(std::vector<PropagatorField>, C_f_side_loop);
|
||||||
std::vector<LatticeComplex> W_f_side_loop(ndim, tmp2);
|
envGetTmp(std::vector<LatticeComplex>, W_i_side_loop);
|
||||||
|
envGetTmp(std::vector<LatticeComplex>, W_f_side_loop);
|
||||||
|
|
||||||
// Setup for C-type contractions.
|
// Setup for C-type contractions.
|
||||||
for (int mu = 0; mu < ndim; ++mu)
|
for (int mu = 0; mu < ndim; ++mu)
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp
|
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.cc
|
Source file: extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.cc
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -78,7 +79,7 @@ std::vector<std::string> TWeakNeutral4ptDisc::getInput(void)
|
|||||||
|
|
||||||
std::vector<std::string> TWeakNeutral4ptDisc::getOutput(void)
|
std::vector<std::string> TWeakNeutral4ptDisc::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -86,7 +87,13 @@ std::vector<std::string> TWeakNeutral4ptDisc::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TWeakNeutral4ptDisc::setup(void)
|
void TWeakNeutral4ptDisc::setup(void)
|
||||||
{
|
{
|
||||||
|
unsigned int ndim = env().getNd();
|
||||||
|
|
||||||
|
envTmpLat(LatticeComplex, "expbuf");
|
||||||
|
envTmpLat(PropagatorField, "tmp");
|
||||||
|
envTmpLat(LatticeComplex, "curr");
|
||||||
|
envTmp(std::vector<PropagatorField>, "meson", 1, ndim, PropagatorField(env().getGrid()));
|
||||||
|
envTmp(std::vector<PropagatorField>, "loop", 1, ndim, PropagatorField(env().getGrid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -97,21 +104,21 @@ void TWeakNeutral4ptDisc::execute(void)
|
|||||||
<< par().q2 << ", '" << par().q3 << "' and '" << par().q4
|
<< par().q2 << ", '" << par().q3 << "' and '" << par().q4
|
||||||
<< "'." << std::endl;
|
<< "'." << std::endl;
|
||||||
|
|
||||||
CorrWriter writer(par().output);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
PropagatorField &q1 = *env().template getObject<PropagatorField>(par().q1);
|
auto &q1 = envGet(PropagatorField, par().q1);
|
||||||
PropagatorField &q2 = *env().template getObject<PropagatorField>(par().q2);
|
auto &q2 = envGet(PropagatorField, par().q2);
|
||||||
PropagatorField &q3 = *env().template getObject<PropagatorField>(par().q3);
|
auto &q3 = envGet(PropagatorField, par().q3);
|
||||||
PropagatorField &q4 = *env().template getObject<PropagatorField>(par().q4);
|
auto &q4 = envGet(PropagatorField, par().q4);
|
||||||
Gamma g5 = Gamma(Gamma::Algebra::Gamma5);
|
Gamma g5 = Gamma(Gamma::Algebra::Gamma5);
|
||||||
LatticeComplex expbuf(env().getGrid());
|
|
||||||
std::vector<TComplex> corrbuf;
|
std::vector<TComplex> corrbuf;
|
||||||
std::vector<Result> result(n_neut_disc_diag);
|
std::vector<Result> result(n_neut_disc_diag);
|
||||||
unsigned int ndim = env().getNd();
|
unsigned int ndim = env().getNd();
|
||||||
|
|
||||||
PropagatorField tmp(env().getGrid());
|
envGetTmp(LatticeComplex, expbuf);
|
||||||
std::vector<PropagatorField> meson(ndim, tmp);
|
envGetTmp(PropagatorField, tmp);
|
||||||
std::vector<PropagatorField> loop(ndim, tmp);
|
envGetTmp(LatticeComplex, curr);
|
||||||
LatticeComplex curr(env().getGrid());
|
envGetTmp(std::vector<PropagatorField>, meson);
|
||||||
|
envGetTmp(std::vector<PropagatorField>, loop);
|
||||||
|
|
||||||
// Setup for type 1 contractions.
|
// Setup for type 1 contractions.
|
||||||
for (int mu = 0; mu < ndim; ++mu)
|
for (int mu = 0; mu < ndim; ++mu)
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp
|
Source file: extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1,3 +1,32 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MFermion/GaugeProp.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
#ifndef Hadrons_MFermion_GaugeProp_hpp_
|
#ifndef Hadrons_MFermion_GaugeProp_hpp_
|
||||||
#define Hadrons_MFermion_GaugeProp_hpp_
|
#define Hadrons_MFermion_GaugeProp_hpp_
|
||||||
|
|
||||||
@ -7,6 +36,27 @@
|
|||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* 5D -> 4D and 4D -> 5D conversions. *
|
||||||
|
******************************************************************************/
|
||||||
|
template<class vobj> // Note that 5D object is modified.
|
||||||
|
inline void make_4D(Lattice<vobj> &in_5d, Lattice<vobj> &out_4d, int Ls)
|
||||||
|
{
|
||||||
|
axpby_ssp_pminus(in_5d, 0., in_5d, 1., in_5d, 0, 0);
|
||||||
|
axpby_ssp_pplus(in_5d, 1., in_5d, 1., in_5d, 0, Ls-1);
|
||||||
|
ExtractSlice(out_4d, in_5d, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class vobj>
|
||||||
|
inline void make_5D(Lattice<vobj> &in_4d, Lattice<vobj> &out_5d, int Ls)
|
||||||
|
{
|
||||||
|
out_5d = zero;
|
||||||
|
InsertSlice(in_4d, out_5d, 0, 0);
|
||||||
|
InsertSlice(in_4d, out_5d, Ls-1, 0);
|
||||||
|
axpby_ssp_pplus(out_5d, 0., out_5d, 1., out_5d, 0, 0);
|
||||||
|
axpby_ssp_pminus(out_5d, 0., out_5d, 1., out_5d, Ls-1, Ls-1);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* GaugeProp *
|
* GaugeProp *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -33,6 +83,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -43,7 +94,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(GaugeProp, TGaugeProp<FIMPL>, MFermion);
|
MODULE_REGISTER_NS(GaugeProp, TGaugeProp<FIMPL>, MFermion);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TGaugeProp implementation *
|
* TGaugeProp implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -75,10 +125,13 @@ template <typename FImpl>
|
|||||||
void TGaugeProp<FImpl>::setup(void)
|
void TGaugeProp<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
Ls_ = env().getObjectLs(par().solver);
|
Ls_ = env().getObjectLs(par().solver);
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
envCreateLat(PropagatorField, getName());
|
||||||
|
envTmpLat(FermionField, "source", Ls_);
|
||||||
|
envTmpLat(FermionField, "sol", Ls_);
|
||||||
|
envTmpLat(FermionField, "tmp");
|
||||||
if (Ls_ > 1)
|
if (Ls_ > 1)
|
||||||
{
|
{
|
||||||
env().template registerLattice<PropagatorField>(getName() + "_5d", Ls_);
|
envCreateLat(PropagatorField, getName() + "_5d", Ls_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,41 +140,34 @@ template <typename FImpl>
|
|||||||
void TGaugeProp<FImpl>::execute(void)
|
void TGaugeProp<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Computing quark propagator '" << getName() << "'"
|
LOG(Message) << "Computing quark propagator '" << getName() << "'"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
FermionField source(env().getGrid(Ls_)), sol(env().getGrid(Ls_)),
|
std::string propName = (Ls_ == 1) ? getName() : (getName() + "_5d");
|
||||||
tmp(env().getGrid());
|
auto &prop = envGet(PropagatorField, propName);
|
||||||
std::string propName = (Ls_ == 1) ? getName() : (getName() + "_5d");
|
auto &fullSrc = envGet(PropagatorField, par().source);
|
||||||
PropagatorField &prop = *env().template createLattice<PropagatorField>(propName);
|
auto &solver = envGet(SolverFn, par().solver);
|
||||||
PropagatorField &fullSrc = *env().template getObject<PropagatorField>(par().source);
|
|
||||||
SolverFn &solver = *env().template getObject<SolverFn>(par().solver);
|
|
||||||
if (Ls_ > 1)
|
|
||||||
{
|
|
||||||
env().template createLattice<PropagatorField>(getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
envGetTmp(FermionField, source);
|
||||||
|
envGetTmp(FermionField, sol);
|
||||||
|
envGetTmp(FermionField, tmp);
|
||||||
LOG(Message) << "Inverting using solver '" << par().solver
|
LOG(Message) << "Inverting using solver '" << par().solver
|
||||||
<< "' on source '" << par().source << "'" << std::endl;
|
<< "' on source '" << par().source << "'" << std::endl;
|
||||||
for (unsigned int s = 0; s < Ns; ++s)
|
for (unsigned int s = 0; s < Ns; ++s)
|
||||||
for (unsigned int c = 0; c < Nc; ++c)
|
for (unsigned int c = 0; c < FImpl::Dimension; ++c)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Inversion for spin= " << s << ", color= " << c
|
LOG(Message) << "Inversion for spin= " << s << ", color= " << c
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
// source conversion for 4D sources
|
// source conversion for 4D sources
|
||||||
if (!env().isObject5d(par().source))
|
if (!env().isObject5d(par().source))
|
||||||
{
|
{
|
||||||
if (Ls_ == 1)
|
if (Ls_ == 1)
|
||||||
{
|
{
|
||||||
PropToFerm(source, fullSrc, s, c);
|
PropToFerm<FImpl>(source, fullSrc, s, c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
source = zero;
|
PropToFerm<FImpl>(tmp, fullSrc, s, c);
|
||||||
PropToFerm(tmp, fullSrc, s, c);
|
make_5D(tmp, source, Ls_);
|
||||||
InsertSlice(tmp, source, 0, 0);
|
|
||||||
InsertSlice(tmp, source, Ls_-1, 0);
|
|
||||||
axpby_ssp_pplus(source, 0., source, 1., source, 0, 0);
|
|
||||||
axpby_ssp_pminus(source, 0., source, 1., source, Ls_-1, Ls_-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// source conversion for 5D sources
|
// source conversion for 5D sources
|
||||||
@ -129,26 +175,22 @@ void TGaugeProp<FImpl>::execute(void)
|
|||||||
{
|
{
|
||||||
if (Ls_ != env().getObjectLs(par().source))
|
if (Ls_ != env().getObjectLs(par().source))
|
||||||
{
|
{
|
||||||
HADRON_ERROR("Ls mismatch between quark action and source");
|
HADRON_ERROR(Size, "Ls mismatch between quark action and source");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PropToFerm(source, fullSrc, s, c);
|
PropToFerm<FImpl>(source, fullSrc, s, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sol = zero;
|
sol = zero;
|
||||||
solver(sol, source);
|
solver(sol, source);
|
||||||
FermToProp(prop, sol, s, c);
|
FermToProp<FImpl>(prop, sol, s, c);
|
||||||
// create 4D propagators from 5D one if necessary
|
// create 4D propagators from 5D one if necessary
|
||||||
if (Ls_ > 1)
|
if (Ls_ > 1)
|
||||||
{
|
{
|
||||||
PropagatorField &p4d =
|
PropagatorField &p4d = envGet(PropagatorField, getName());
|
||||||
*env().template getObject<PropagatorField>(getName());
|
make_4D(sol, tmp, Ls_);
|
||||||
|
FermToProp<FImpl>(p4d, tmp, s, c);
|
||||||
axpby_ssp_pminus(sol, 0., sol, 1., sol, 0, 0);
|
|
||||||
axpby_ssp_pplus(sol, 1., sol, 1., sol, 0, Ls_-1);
|
|
||||||
ExtractSlice(tmp, sol, 0, 0);
|
|
||||||
FermToProp(p4d, tmp, s, c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
extras/Hadrons/Modules/MGauge/FundtoHirep.cc
Normal file
75
extras/Hadrons/Modules/MGauge/FundtoHirep.cc
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/FundtoHirep.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
|
||||||
|
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/Hadrons/Modules/MGauge/FundtoHirep.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace MGauge;
|
||||||
|
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <class Rep>
|
||||||
|
TFundtoHirep<Rep>::TFundtoHirep(const std::string name)
|
||||||
|
: Module<FundtoHirepPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <class Rep>
|
||||||
|
std::vector<std::string> TFundtoHirep<Rep>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Rep>
|
||||||
|
std::vector<std::string> TFundtoHirep<Rep>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Rep>
|
||||||
|
void TFundtoHirep<Rep>::setup(void)
|
||||||
|
{
|
||||||
|
envCreateLat(typename Rep::LatticeField, getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <class Rep>
|
||||||
|
void TFundtoHirep<Rep>::execute(void)
|
||||||
|
{
|
||||||
|
auto &U = *env().template getObject<LatticeGaugeField>(par().gaugeconf);
|
||||||
|
LOG(Message) << "Transforming Representation" << std::endl;
|
||||||
|
|
||||||
|
Rep TargetRepresentation(U._grid);
|
||||||
|
TargetRepresentation.update_representation(U);
|
||||||
|
|
||||||
|
auto &URep = envGet(typename Rep::LatticeField, getName());
|
||||||
|
URep = TargetRepresentation.U;
|
||||||
|
}
|
77
extras/Hadrons/Modules/MGauge/FundtoHirep.hpp
Normal file
77
extras/Hadrons/Modules/MGauge/FundtoHirep.hpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/FundtoHirep.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
Author: David Preti <david.preti@to.infn.it>
|
||||||
|
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_MGauge_FundtoHirep_hpp_
|
||||||
|
#define Hadrons_MGauge_FundtoHirep_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Load a NERSC configuration *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MGauge)
|
||||||
|
|
||||||
|
class FundtoHirepPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(FundtoHirepPar,
|
||||||
|
std::string, gaugeconf);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Rep>
|
||||||
|
class TFundtoHirep: public Module<FundtoHirepPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TFundtoHirep(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TFundtoHirep(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
void setup(void);
|
||||||
|
// execution
|
||||||
|
void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
//MODULE_REGISTER_NS(FundtoAdjoint, TFundtoHirep<AdjointRepresentation>, MGauge);
|
||||||
|
//MODULE_REGISTER_NS(FundtoTwoIndexSym, TFundtoHirep<TwoIndexSymmetricRepresentation>, MGauge);
|
||||||
|
//MODULE_REGISTER_NS(FundtoTwoIndexAsym, TFundtoHirep<TwoIndexAntiSymmetricRepresentation>, MGauge);
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MGauge_FundtoHirep_hpp_
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/Random.cc
|
Source file: extras/Hadrons/Modules/MGauge/Random.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -44,7 +43,9 @@ TRandom::TRandom(const std::string name)
|
|||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
std::vector<std::string> TRandom::getInput(void)
|
std::vector<std::string> TRandom::getInput(void)
|
||||||
{
|
{
|
||||||
return std::vector<std::string>();
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> TRandom::getOutput(void)
|
std::vector<std::string> TRandom::getOutput(void)
|
||||||
@ -57,13 +58,14 @@ std::vector<std::string> TRandom::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TRandom::setup(void)
|
void TRandom::setup(void)
|
||||||
{
|
{
|
||||||
env().registerLattice<LatticeGaugeField>(getName());
|
envCreateLat(LatticeGaugeField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
void TRandom::execute(void)
|
void TRandom::execute(void)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Generating random gauge configuration" << std::endl;
|
LOG(Message) << "Generating random gauge configuration" << std::endl;
|
||||||
LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
|
|
||||||
|
auto &U = envGet(LatticeGaugeField, getName());
|
||||||
SU3::HotConfiguration(*env().get4dRng(), U);
|
SU3::HotConfiguration(*env().get4dRng(), U);
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/Random.hpp
|
Source file: extras/Hadrons/Modules/MGauge/Random.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -51,6 +50,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
|
@ -4,9 +4,9 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/StochEm.cc
|
Source file: extras/Hadrons/Modules/MGauge/StochEm.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -57,32 +57,28 @@ std::vector<std::string> TStochEm::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TStochEm::setup(void)
|
void TStochEm::setup(void)
|
||||||
{
|
{
|
||||||
if (!env().hasRegisteredObject("_" + getName() + "_weight"))
|
if (!env().hasCreatedObject("_" + getName() + "_weight"))
|
||||||
{
|
{
|
||||||
env().registerLattice<EmComp>("_" + getName() + "_weight");
|
envCacheLat(EmComp, "_" + getName() + "_weight");
|
||||||
}
|
}
|
||||||
env().registerLattice<EmField>(getName());
|
envCreateLat(EmField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
void TStochEm::execute(void)
|
void TStochEm::execute(void)
|
||||||
{
|
{
|
||||||
|
LOG(Message) << "Generating stochatic EM potential..." << std::endl;
|
||||||
|
|
||||||
PhotonR photon(par().gauge, par().zmScheme);
|
PhotonR photon(par().gauge, par().zmScheme);
|
||||||
EmField &a = *env().createLattice<EmField>(getName());
|
auto &a = envGet(EmField, getName());
|
||||||
EmComp *w;
|
auto &w = envGet(EmComp, "_" + getName() + "_weight");
|
||||||
|
|
||||||
if (!env().hasCreatedObject("_" + getName() + "_weight"))
|
if (!env().hasCreatedObject("_" + getName() + "_weight"))
|
||||||
{
|
{
|
||||||
LOG(Message) << "Caching stochatic EM potential weight (gauge: "
|
LOG(Message) << "Caching stochatic EM potential weight (gauge: "
|
||||||
<< par().gauge << ", zero-mode scheme: "
|
<< par().gauge << ", zero-mode scheme: "
|
||||||
<< par().zmScheme << ")..." << std::endl;
|
<< par().zmScheme << ")..." << std::endl;
|
||||||
w = env().createLattice<EmComp>("_" + getName() + "_weight");
|
photon.StochasticWeight(w);
|
||||||
photon.StochasticWeight(*w);
|
|
||||||
}
|
}
|
||||||
else
|
photon.StochasticField(a, *env().get4dRng(), w);
|
||||||
{
|
|
||||||
w = env().getObject<EmComp>("_" + getName() + "_weight");
|
|
||||||
}
|
|
||||||
LOG(Message) << "Generating stochatic EM potential..." << std::endl;
|
|
||||||
photon.StochasticField(a, *env().get4dRng(), *w);
|
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/StochEm.hpp
|
Source file: extras/Hadrons/Modules/MGauge/StochEm.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -60,6 +60,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/Unit.cc
|
Source file: extras/Hadrons/Modules/MGauge/Unit.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -57,13 +56,14 @@ std::vector<std::string> TUnit::getOutput(void)
|
|||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TUnit::setup(void)
|
void TUnit::setup(void)
|
||||||
{
|
{
|
||||||
env().registerLattice<LatticeGaugeField>(getName());
|
envCreateLat(LatticeGaugeField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
void TUnit::execute(void)
|
void TUnit::execute(void)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Creating unit gauge configuration" << std::endl;
|
LOG(Message) << "Creating unit gauge configuration" << std::endl;
|
||||||
LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
|
|
||||||
|
auto &U = envGet(LatticeGaugeField, getName());
|
||||||
SU3::ColdConfiguration(*env().get4dRng(), U);
|
SU3::ColdConfiguration(*env().get4dRng(), U);
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/Unit.hpp
|
Source file: extras/Hadrons/Modules/MGauge/Unit.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -51,6 +50,7 @@ public:
|
|||||||
// dependencies/products
|
// dependencies/products
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
|
140
extras/Hadrons/Modules/MIO/LoadBinary.hpp
Normal file
140
extras/Hadrons/Modules/MIO/LoadBinary.hpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MIO/LoadBinary.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MIO_LoadBinary_hpp_
|
||||||
|
#define Hadrons_MIO_LoadBinary_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Load a binary configurations *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MIO)
|
||||||
|
|
||||||
|
class LoadBinaryPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LoadBinaryPar,
|
||||||
|
std::string, file,
|
||||||
|
std::string, format);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Impl>
|
||||||
|
class TLoadBinary: public Module<LoadBinaryPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Impl::Field Field;
|
||||||
|
typedef typename Impl::Simd Simd;
|
||||||
|
typedef typename Field::vector_object vobj;
|
||||||
|
typedef typename vobj::scalar_object sobj;
|
||||||
|
typedef typename sobj::DoublePrecision sobj_double;
|
||||||
|
typedef BinarySimpleMunger<sobj_double, sobj> Munger;
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TLoadBinary(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TLoadBinary(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(LoadBinary, TLoadBinary<GIMPL>, MIO);
|
||||||
|
MODULE_REGISTER_NS(LoadBinaryScalarSU2, TLoadBinary<ScalarNxNAdjImplR<2>>, MIO);
|
||||||
|
MODULE_REGISTER_NS(LoadBinaryScalarSU3, TLoadBinary<ScalarNxNAdjImplR<3>>, MIO);
|
||||||
|
MODULE_REGISTER_NS(LoadBinaryScalarSU4, TLoadBinary<ScalarNxNAdjImplR<4>>, MIO);
|
||||||
|
MODULE_REGISTER_NS(LoadBinaryScalarSU5, TLoadBinary<ScalarNxNAdjImplR<5>>, MIO);
|
||||||
|
MODULE_REGISTER_NS(LoadBinaryScalarSU6, TLoadBinary<ScalarNxNAdjImplR<6>>, MIO);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TLoadBinary implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Impl>
|
||||||
|
TLoadBinary<Impl>::TLoadBinary(const std::string name)
|
||||||
|
: Module<LoadBinaryPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename Impl>
|
||||||
|
std::vector<std::string> TLoadBinary<Impl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Impl>
|
||||||
|
std::vector<std::string> TLoadBinary<Impl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Impl>
|
||||||
|
void TLoadBinary<Impl>::setup(void)
|
||||||
|
{
|
||||||
|
envCreateLat(Field, getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename Impl>
|
||||||
|
void TLoadBinary<Impl>::execute(void)
|
||||||
|
{
|
||||||
|
Munger munge;
|
||||||
|
uint32_t nersc_csum, scidac_csuma, scidac_csumb;
|
||||||
|
auto &U = envGet(Field, getName());
|
||||||
|
std::string filename = par().file + "."
|
||||||
|
+ std::to_string(vm().getTrajectory());
|
||||||
|
|
||||||
|
LOG(Message) << "Loading " << par().format
|
||||||
|
<< " binary configuration from file '" << filename
|
||||||
|
<< "'" << std::endl;
|
||||||
|
BinaryIO::readLatticeObject<vobj, sobj_double>(U, filename, munge, 0,
|
||||||
|
par().format, nersc_csum,
|
||||||
|
scidac_csuma, scidac_csumb);
|
||||||
|
LOG(Message) << "Checksums:" << std::endl;
|
||||||
|
LOG(Message) << " NERSC " << nersc_csum << std::endl;
|
||||||
|
LOG(Message) << " SciDAC A " << scidac_csuma << std::endl;
|
||||||
|
LOG(Message) << " SciDAC B " << scidac_csumb << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MIO_LoadBinary_hpp_
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/Load.cc
|
Source file: extras/Hadrons/Modules/MIO/LoadNersc.cc
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -26,30 +25,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
See the full license in the file "LICENSE" in the top level distribution directory
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
|
#include <Grid/Hadrons/Modules/MIO/LoadNersc.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
|
|
||||||
|
|
||||||
using namespace Grid;
|
using namespace Grid;
|
||||||
using namespace Hadrons;
|
using namespace Hadrons;
|
||||||
using namespace MGauge;
|
using namespace MIO;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TLoad implementation *
|
* TLoadNersc implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
// constructor /////////////////////////////////////////////////////////////////
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
TLoad::TLoad(const std::string name)
|
TLoadNersc::TLoadNersc(const std::string name)
|
||||||
: Module<LoadPar>(name)
|
: Module<LoadNerscPar>(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
std::vector<std::string> TLoad::getInput(void)
|
std::vector<std::string> TLoadNersc::getInput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> in;
|
std::vector<std::string> in;
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> TLoad::getOutput(void)
|
std::vector<std::string> TLoadNersc::getOutput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> out = {getName()};
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
@ -57,21 +55,21 @@ std::vector<std::string> TLoad::getOutput(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup ///////////////////////////////////////////////////////////////////////
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
void TLoad::setup(void)
|
void TLoadNersc::setup(void)
|
||||||
{
|
{
|
||||||
env().registerLattice<LatticeGaugeField>(getName());
|
envCreateLat(LatticeGaugeField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
void TLoad::execute(void)
|
void TLoadNersc::execute(void)
|
||||||
{
|
{
|
||||||
FieldMetaData header;
|
FieldMetaData header;
|
||||||
std::string fileName = par().file + "."
|
std::string fileName = par().file + "."
|
||||||
+ std::to_string(env().getTrajectory());
|
+ std::to_string(vm().getTrajectory());
|
||||||
|
|
||||||
LOG(Message) << "Loading NERSC configuration from file '" << fileName
|
LOG(Message) << "Loading NERSC configuration from file '" << fileName
|
||||||
<< "'" << std::endl;
|
<< "'" << std::endl;
|
||||||
LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
|
|
||||||
|
auto &U = envGet(LatticeGaugeField, getName());
|
||||||
NerscIO::readConfiguration(U, header, fileName);
|
NerscIO::readConfiguration(U, header, fileName);
|
||||||
LOG(Message) << "NERSC header:" << std::endl;
|
LOG(Message) << "NERSC header:" << std::endl;
|
||||||
dump_meta_data(header, LOG(Message));
|
dump_meta_data(header, LOG(Message));
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MGauge/Load.hpp
|
Source file: extras/Hadrons/Modules/MIO/LoadNersc.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -26,9 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
See the full license in the file "LICENSE" in the top level distribution directory
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MIO_LoadNersc_hpp_
|
||||||
#ifndef Hadrons_MGauge_Load_hpp_
|
#define Hadrons_MIO_LoadNersc_hpp_
|
||||||
#define Hadrons_MGauge_Load_hpp_
|
|
||||||
|
|
||||||
#include <Grid/Hadrons/Global.hpp>
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
#include <Grid/Hadrons/Module.hpp>
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
@ -37,24 +35,24 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Load a NERSC configuration *
|
* Load a NERSC configuration *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
BEGIN_MODULE_NAMESPACE(MGauge)
|
BEGIN_MODULE_NAMESPACE(MIO)
|
||||||
|
|
||||||
class LoadPar: Serializable
|
class LoadNerscPar: Serializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LoadPar,
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LoadNerscPar,
|
||||||
std::string, file);
|
std::string, file);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TLoad: public Module<LoadPar>
|
class TLoadNersc: public Module<LoadNerscPar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
TLoad(const std::string name);
|
TLoadNersc(const std::string name);
|
||||||
// destructor
|
// destructor
|
||||||
virtual ~TLoad(void) = default;
|
virtual ~TLoadNersc(void) = default;
|
||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
@ -64,10 +62,10 @@ public:
|
|||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(Load, TLoad, MGauge);
|
MODULE_REGISTER_NS(LoadNersc, TLoadNersc, MIO);
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
#endif // Hadrons_MGauge_Load_hpp_
|
#endif // Hadrons_MIO_LoadNersc_hpp_
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MLoop/NoiseLoop.hpp
|
Source file: extras/Hadrons/Modules/MLoop/NoiseLoop.hpp
|
||||||
|
|
||||||
Copyright (C) 2016
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -74,6 +75,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -112,16 +114,16 @@ std::vector<std::string> TNoiseLoop<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TNoiseLoop<FImpl>::setup(void)
|
void TNoiseLoop<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
envCreateLat(PropagatorField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TNoiseLoop<FImpl>::execute(void)
|
void TNoiseLoop<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
PropagatorField &loop = *env().template createLattice<PropagatorField>(getName());
|
auto &loop = envGet(PropagatorField, getName());
|
||||||
PropagatorField &q = *env().template getObject<PropagatorField>(par().q);
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
PropagatorField &eta = *env().template getObject<PropagatorField>(par().eta);
|
auto &eta = envGet(PropagatorField, par().eta);
|
||||||
loop = q*adj(eta);
|
loop = q*adj(eta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,31 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalar/ChargedProp.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: James Harrison <jch1g10@soton.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/Hadrons/Modules/MScalar/ChargedProp.hpp>
|
#include <Grid/Hadrons/Modules/MScalar/ChargedProp.hpp>
|
||||||
#include <Grid/Hadrons/Modules/MScalar/Scalar.hpp>
|
#include <Grid/Hadrons/Modules/MScalar/Scalar.hpp>
|
||||||
|
|
||||||
@ -37,89 +65,43 @@ void TChargedProp::setup(void)
|
|||||||
{
|
{
|
||||||
phaseName_.push_back("_shiftphase_" + std::to_string(mu));
|
phaseName_.push_back("_shiftphase_" + std::to_string(mu));
|
||||||
}
|
}
|
||||||
GFSrcName_ = "_" + getName() + "_DinvSrc";
|
GFSrcName_ = getName() + "_DinvSrc";
|
||||||
if (!env().hasRegisteredObject(freeMomPropName_))
|
fftName_ = getName() + "_fft";
|
||||||
|
|
||||||
|
freeMomPropDone_ = env().hasCreatedObject(freeMomPropName_);
|
||||||
|
GFSrcDone_ = env().hasCreatedObject(GFSrcName_);
|
||||||
|
phasesDone_ = env().hasCreatedObject(phaseName_[0]);
|
||||||
|
envCacheLat(ScalarField, freeMomPropName_);
|
||||||
|
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
||||||
{
|
{
|
||||||
env().registerLattice<ScalarField>(freeMomPropName_);
|
envCacheLat(ScalarField, phaseName_[mu]);
|
||||||
}
|
}
|
||||||
if (!env().hasRegisteredObject(phaseName_[0]))
|
envCacheLat(ScalarField, GFSrcName_);
|
||||||
{
|
envCreateLat(ScalarField, getName());
|
||||||
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
envTmpLat(ScalarField, "buf");
|
||||||
{
|
envTmpLat(ScalarField, "result");
|
||||||
env().registerLattice<ScalarField>(phaseName_[mu]);
|
envTmpLat(ScalarField, "Amu");
|
||||||
}
|
envCache(FFT, fftName_, 1, env().getGrid());
|
||||||
}
|
|
||||||
if (!env().hasRegisteredObject(GFSrcName_))
|
|
||||||
{
|
|
||||||
env().registerLattice<ScalarField>(GFSrcName_);
|
|
||||||
}
|
|
||||||
env().registerLattice<ScalarField>(getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
void TChargedProp::execute(void)
|
void TChargedProp::execute(void)
|
||||||
{
|
{
|
||||||
// CACHING ANALYTIC EXPRESSIONS
|
// CACHING ANALYTIC EXPRESSIONS
|
||||||
ScalarField &source = *env().getObject<ScalarField>(par().source);
|
makeCaches();
|
||||||
Complex ci(0.0,1.0);
|
|
||||||
FFT fft(env().getGrid());
|
|
||||||
|
|
||||||
// cache free scalar propagator
|
|
||||||
if (!env().hasCreatedObject(freeMomPropName_))
|
|
||||||
{
|
|
||||||
LOG(Message) << "Caching momentum space free scalar propagator"
|
|
||||||
<< " (mass= " << par().mass << ")..." << std::endl;
|
|
||||||
freeMomProp_ = env().createLattice<ScalarField>(freeMomPropName_);
|
|
||||||
SIMPL::MomentumSpacePropagator(*freeMomProp_, par().mass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
freeMomProp_ = env().getObject<ScalarField>(freeMomPropName_);
|
|
||||||
}
|
|
||||||
// cache G*F*src
|
|
||||||
if (!env().hasCreatedObject(GFSrcName_))
|
|
||||||
|
|
||||||
{
|
|
||||||
GFSrc_ = env().createLattice<ScalarField>(GFSrcName_);
|
|
||||||
fft.FFT_all_dim(*GFSrc_, source, FFT::forward);
|
|
||||||
*GFSrc_ = (*freeMomProp_)*(*GFSrc_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GFSrc_ = env().getObject<ScalarField>(GFSrcName_);
|
|
||||||
}
|
|
||||||
// cache phases
|
|
||||||
if (!env().hasCreatedObject(phaseName_[0]))
|
|
||||||
{
|
|
||||||
std::vector<int> &l = env().getGrid()->_fdimensions;
|
|
||||||
|
|
||||||
LOG(Message) << "Caching shift phases..." << std::endl;
|
|
||||||
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
|
||||||
{
|
|
||||||
Real twoPiL = M_PI*2./l[mu];
|
|
||||||
|
|
||||||
phase_.push_back(env().createLattice<ScalarField>(phaseName_[mu]));
|
|
||||||
LatticeCoordinate(*(phase_[mu]), mu);
|
|
||||||
*(phase_[mu]) = exp(ci*twoPiL*(*(phase_[mu])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
|
||||||
{
|
|
||||||
phase_.push_back(env().getObject<ScalarField>(phaseName_[mu]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PROPAGATOR CALCULATION
|
// PROPAGATOR CALCULATION
|
||||||
LOG(Message) << "Computing charged scalar propagator"
|
LOG(Message) << "Computing charged scalar propagator"
|
||||||
<< " (mass= " << par().mass
|
<< " (mass= " << par().mass
|
||||||
<< ", charge= " << par().charge << ")..." << std::endl;
|
<< ", charge= " << par().charge << ")..." << std::endl;
|
||||||
|
|
||||||
ScalarField &prop = *env().createLattice<ScalarField>(getName());
|
auto &prop = envGet(ScalarField, getName());
|
||||||
ScalarField buf(env().getGrid());
|
auto &GFSrc = envGet(ScalarField, GFSrcName_);
|
||||||
ScalarField &GFSrc = *GFSrc_, &G = *freeMomProp_;
|
auto &G = envGet(ScalarField, freeMomPropName_);
|
||||||
double q = par().charge;
|
auto &fft = envGet(FFT, fftName_);
|
||||||
|
double q = par().charge;
|
||||||
|
envGetTmp(ScalarField, result);
|
||||||
|
envGetTmp(ScalarField, buf);
|
||||||
|
|
||||||
// G*F*Src
|
// G*F*Src
|
||||||
prop = GFSrc;
|
prop = GFSrc;
|
||||||
@ -146,12 +128,12 @@ void TChargedProp::execute(void)
|
|||||||
if (!par().output.empty())
|
if (!par().output.empty())
|
||||||
{
|
{
|
||||||
std::string filename = par().output + "." +
|
std::string filename = par().output + "." +
|
||||||
std::to_string(env().getTrajectory());
|
std::to_string(vm().getTrajectory());
|
||||||
|
|
||||||
LOG(Message) << "Saving zero-momentum projection to '"
|
LOG(Message) << "Saving zero-momentum projection to '"
|
||||||
<< filename << "'..." << std::endl;
|
<< filename << "'..." << std::endl;
|
||||||
|
|
||||||
CorrWriter writer(filename);
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
std::vector<TComplex> vecBuf;
|
std::vector<TComplex> vecBuf;
|
||||||
std::vector<Complex> result;
|
std::vector<Complex> result;
|
||||||
|
|
||||||
@ -166,15 +148,55 @@ void TChargedProp::execute(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TChargedProp::makeCaches(void)
|
||||||
|
{
|
||||||
|
auto &freeMomProp = envGet(ScalarField, freeMomPropName_);
|
||||||
|
auto &GFSrc = envGet(ScalarField, GFSrcName_);
|
||||||
|
auto &fft = envGet(FFT, fftName_);
|
||||||
|
|
||||||
|
if (!freeMomPropDone_)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Caching momentum space free scalar propagator"
|
||||||
|
<< " (mass= " << par().mass << ")..." << std::endl;
|
||||||
|
SIMPL::MomentumSpacePropagator(freeMomProp, par().mass);
|
||||||
|
}
|
||||||
|
if (!GFSrcDone_)
|
||||||
|
{
|
||||||
|
FFT fft(env().getGrid());
|
||||||
|
auto &source = envGet(ScalarField, par().source);
|
||||||
|
|
||||||
|
LOG(Message) << "Caching G*F*src..." << std::endl;
|
||||||
|
fft.FFT_all_dim(GFSrc, source, FFT::forward);
|
||||||
|
GFSrc = freeMomProp*GFSrc;
|
||||||
|
}
|
||||||
|
if (!phasesDone_)
|
||||||
|
{
|
||||||
|
std::vector<int> &l = env().getGrid()->_fdimensions;
|
||||||
|
Complex ci(0.0,1.0);
|
||||||
|
|
||||||
|
LOG(Message) << "Caching shift phases..." << std::endl;
|
||||||
|
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
||||||
|
{
|
||||||
|
Real twoPiL = M_PI*2./l[mu];
|
||||||
|
auto &phmu = envGet(ScalarField, phaseName_[mu]);
|
||||||
|
|
||||||
|
LatticeCoordinate(phmu, mu);
|
||||||
|
phmu = exp(ci*twoPiL*phmu);
|
||||||
|
phase_.push_back(&phmu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TChargedProp::momD1(ScalarField &s, FFT &fft)
|
void TChargedProp::momD1(ScalarField &s, FFT &fft)
|
||||||
{
|
{
|
||||||
EmField &A = *env().getObject<EmField>(par().emField);
|
auto &A = envGet(EmField, par().emField);
|
||||||
ScalarField buf(env().getGrid()), result(env().getGrid()),
|
|
||||||
Amu(env().getGrid());
|
|
||||||
Complex ci(0.0,1.0);
|
Complex ci(0.0,1.0);
|
||||||
|
|
||||||
result = zero;
|
envGetTmp(ScalarField, buf);
|
||||||
|
envGetTmp(ScalarField, result);
|
||||||
|
envGetTmp(ScalarField, Amu);
|
||||||
|
|
||||||
|
result = zero;
|
||||||
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
||||||
{
|
{
|
||||||
Amu = peekLorentz(A, mu);
|
Amu = peekLorentz(A, mu);
|
||||||
@ -198,12 +220,13 @@ void TChargedProp::momD1(ScalarField &s, FFT &fft)
|
|||||||
|
|
||||||
void TChargedProp::momD2(ScalarField &s, FFT &fft)
|
void TChargedProp::momD2(ScalarField &s, FFT &fft)
|
||||||
{
|
{
|
||||||
EmField &A = *env().getObject<EmField>(par().emField);
|
auto &A = envGet(EmField, par().emField);
|
||||||
ScalarField buf(env().getGrid()), result(env().getGrid()),
|
|
||||||
Amu(env().getGrid());
|
envGetTmp(ScalarField, buf);
|
||||||
|
envGetTmp(ScalarField, result);
|
||||||
|
envGetTmp(ScalarField, Amu);
|
||||||
|
|
||||||
result = zero;
|
result = zero;
|
||||||
|
|
||||||
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
for (unsigned int mu = 0; mu < env().getNd(); ++mu)
|
||||||
{
|
{
|
||||||
Amu = peekLorentz(A, mu);
|
Amu = peekLorentz(A, mu);
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalar/ChargedProp.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
#ifndef Hadrons_MScalar_ChargedProp_hpp_
|
#ifndef Hadrons_MScalar_ChargedProp_hpp_
|
||||||
#define Hadrons_MScalar_ChargedProp_hpp_
|
#define Hadrons_MScalar_ChargedProp_hpp_
|
||||||
|
|
||||||
@ -37,19 +64,20 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
private:
|
private:
|
||||||
|
void makeCaches(void);
|
||||||
void momD1(ScalarField &s, FFT &fft);
|
void momD1(ScalarField &s, FFT &fft);
|
||||||
void momD2(ScalarField &s, FFT &fft);
|
void momD2(ScalarField &s, FFT &fft);
|
||||||
private:
|
private:
|
||||||
std::string freeMomPropName_, GFSrcName_;
|
bool freeMomPropDone_, GFSrcDone_, phasesDone_;
|
||||||
|
std::string freeMomPropName_, GFSrcName_, fftName_;
|
||||||
std::vector<std::string> phaseName_;
|
std::vector<std::string> phaseName_;
|
||||||
ScalarField *freeMomProp_, *GFSrc_;
|
|
||||||
std::vector<ScalarField *> phase_;
|
std::vector<ScalarField *> phase_;
|
||||||
EmField *A;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(ChargedProp, TChargedProp, MScalar);
|
MODULE_REGISTER_NS(ChargedProp, TChargedProp, MScalar);
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalar/FreeProp.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
#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>
|
||||||
|
|
||||||
@ -33,38 +60,31 @@ void TFreeProp::setup(void)
|
|||||||
{
|
{
|
||||||
freeMomPropName_ = FREEMOMPROP(par().mass);
|
freeMomPropName_ = FREEMOMPROP(par().mass);
|
||||||
|
|
||||||
if (!env().hasRegisteredObject(freeMomPropName_))
|
freePropDone_ = env().hasCreatedObject(freeMomPropName_);
|
||||||
{
|
envCacheLat(ScalarField, freeMomPropName_);
|
||||||
env().registerLattice<ScalarField>(freeMomPropName_);
|
envCreateLat(ScalarField, getName());
|
||||||
}
|
|
||||||
env().registerLattice<ScalarField>(getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
void TFreeProp::execute(void)
|
void TFreeProp::execute(void)
|
||||||
{
|
{
|
||||||
ScalarField &prop = *env().createLattice<ScalarField>(getName());
|
auto &freeMomProp = envGet(ScalarField, freeMomPropName_);
|
||||||
ScalarField &source = *env().getObject<ScalarField>(par().source);
|
auto &prop = envGet(ScalarField, getName());
|
||||||
ScalarField *freeMomProp;
|
auto &source = envGet(ScalarField, par().source);
|
||||||
|
|
||||||
if (!env().hasCreatedObject(freeMomPropName_))
|
if (!freePropDone_)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Caching momentum space free scalar propagator"
|
LOG(Message) << "Caching momentum space free scalar propagator"
|
||||||
<< " (mass= " << par().mass << ")..." << std::endl;
|
<< " (mass= " << par().mass << ")..." << std::endl;
|
||||||
freeMomProp = env().createLattice<ScalarField>(freeMomPropName_);
|
SIMPL::MomentumSpacePropagator(freeMomProp, par().mass);
|
||||||
SIMPL::MomentumSpacePropagator(*freeMomProp, par().mass);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
freeMomProp = env().getObject<ScalarField>(freeMomPropName_);
|
|
||||||
}
|
}
|
||||||
LOG(Message) << "Computing free scalar propagator..." << std::endl;
|
LOG(Message) << "Computing free scalar propagator..." << std::endl;
|
||||||
SIMPL::FreePropagator(source, prop, *freeMomProp);
|
SIMPL::FreePropagator(source, prop, freeMomProp);
|
||||||
|
|
||||||
if (!par().output.empty())
|
if (!par().output.empty())
|
||||||
{
|
{
|
||||||
TextWriter writer(par().output + "." +
|
TextWriter writer(par().output + "." +
|
||||||
std::to_string(env().getTrajectory()));
|
std::to_string(vm().getTrajectory()));
|
||||||
std::vector<TComplex> buf;
|
std::vector<TComplex> buf;
|
||||||
std::vector<Complex> result;
|
std::vector<Complex> result;
|
||||||
|
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalar/FreeProp.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
#ifndef Hadrons_MScalar_FreeProp_hpp_
|
#ifndef Hadrons_MScalar_FreeProp_hpp_
|
||||||
#define Hadrons_MScalar_FreeProp_hpp_
|
#define Hadrons_MScalar_FreeProp_hpp_
|
||||||
|
|
||||||
@ -33,12 +60,14 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
private:
|
private:
|
||||||
std::string freeMomPropName_;
|
std::string freeMomPropName_;
|
||||||
|
bool freePropDone_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(FreeProp, TFreeProp, MScalar);
|
MODULE_REGISTER_NS(FreeProp, TFreeProp, MScalar);
|
||||||
|
@ -1,3 +1,30 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalar/Scalar.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
#ifndef Hadrons_Scalar_hpp_
|
#ifndef Hadrons_Scalar_hpp_
|
||||||
#define Hadrons_Scalar_hpp_
|
#define Hadrons_Scalar_hpp_
|
||||||
|
|
||||||
|
166
extras/Hadrons/Modules/MScalarSUN/Div.hpp
Normal file
166
extras/Hadrons/Modules/MScalarSUN/Div.hpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalarSUN/Div.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MScalarSUN_Div_hpp_
|
||||||
|
#define Hadrons_MScalarSUN_Div_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Div *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MScalarSUN)
|
||||||
|
|
||||||
|
class DivPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_ENUM(DiffType, undef, forward, 1, backward, 2, central, 3);
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(DivPar,
|
||||||
|
std::vector<std::string>, op,
|
||||||
|
DiffType, type,
|
||||||
|
std::string, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
class TDiv: public Module<DivPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename SImpl::Field Field;
|
||||||
|
typedef typename SImpl::ComplexField ComplexField;
|
||||||
|
class Result: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||||
|
DivPar::DiffType, type,
|
||||||
|
Complex, value);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TDiv(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TDiv(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(DivSU2, TDiv<ScalarNxNAdjImplR<2>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(DivSU3, TDiv<ScalarNxNAdjImplR<3>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(DivSU4, TDiv<ScalarNxNAdjImplR<4>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(DivSU5, TDiv<ScalarNxNAdjImplR<5>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(DivSU6, TDiv<ScalarNxNAdjImplR<6>>, MScalarSUN);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TDiv implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
TDiv<SImpl>::TDiv(const std::string name)
|
||||||
|
: Module<DivPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TDiv<SImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
return par().op;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TDiv<SImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TDiv<SImpl>::setup(void)
|
||||||
|
{
|
||||||
|
if (par().op.size() != env().getNd())
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Size, "the number of components differs from number of dimensions");
|
||||||
|
}
|
||||||
|
envCreateLat(ComplexField, getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TDiv<SImpl>::execute(void)
|
||||||
|
{
|
||||||
|
const auto nd = env().getNd();
|
||||||
|
|
||||||
|
LOG(Message) << "Computing the " << par().type << " divergence of [";
|
||||||
|
for (unsigned int mu = 0; mu < nd; ++mu)
|
||||||
|
{
|
||||||
|
std::cout << par().op[mu] << ((mu == nd - 1) ? "]" : ", ");
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
auto &div = envGet(ComplexField, getName());
|
||||||
|
div = zero;
|
||||||
|
for (unsigned int mu = 0; mu < nd; ++mu)
|
||||||
|
{
|
||||||
|
auto &op = envGet(ComplexField, par().op[mu]);
|
||||||
|
switch(par().type)
|
||||||
|
{
|
||||||
|
case DivPar::DiffType::backward:
|
||||||
|
div += op - Cshift(op, mu, -1);
|
||||||
|
break;
|
||||||
|
case DivPar::DiffType::forward:
|
||||||
|
div += Cshift(op, mu, 1) - op;
|
||||||
|
break;
|
||||||
|
case DivPar::DiffType::central:
|
||||||
|
div += 0.5*(Cshift(op, mu, 1) - Cshift(op, mu, -1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!par().output.empty())
|
||||||
|
{
|
||||||
|
Result r;
|
||||||
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
|
|
||||||
|
r.type = par().type;
|
||||||
|
r.value = TensorRemove(sum(div));
|
||||||
|
write(writer, "div", r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MScalarSUN_Div_hpp_
|
146
extras/Hadrons/Modules/MScalarSUN/TrMag.hpp
Normal file
146
extras/Hadrons/Modules/MScalarSUN/TrMag.hpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalarSUN/TrMag.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MScalarSUN_TrMag_hpp_
|
||||||
|
#define Hadrons_MScalarSUN_TrMag_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Module to compute tr(mag^n) *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MScalarSUN)
|
||||||
|
|
||||||
|
class TrMagPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(TrMagPar,
|
||||||
|
std::string, field,
|
||||||
|
unsigned int, maxPow,
|
||||||
|
std::string, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
class TTrMag: public Module<TrMagPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename SImpl::Field Field;
|
||||||
|
typedef typename SImpl::ComplexField ComplexField;
|
||||||
|
class Result: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||||
|
std::string, op,
|
||||||
|
Real, value);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TTrMag(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TTrMag(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(TrMagSU2, TTrMag<ScalarNxNAdjImplR<2>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrMagSU3, TTrMag<ScalarNxNAdjImplR<3>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrMagSU4, TTrMag<ScalarNxNAdjImplR<4>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrMagSU5, TTrMag<ScalarNxNAdjImplR<5>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrMagSU6, TTrMag<ScalarNxNAdjImplR<6>>, MScalarSUN);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TTrMag implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
TTrMag<SImpl>::TTrMag(const std::string name)
|
||||||
|
: Module<TrMagPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TTrMag<SImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().field};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TTrMag<SImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TTrMag<SImpl>::setup(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TTrMag<SImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Computing tr(mag^n) for n even up to " << par().maxPow
|
||||||
|
<< "..." << std::endl;
|
||||||
|
|
||||||
|
std::vector<Result> result;
|
||||||
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
|
auto &phi = envGet(Field, par().field);
|
||||||
|
|
||||||
|
auto m2 = sum(phi), mn = m2;
|
||||||
|
|
||||||
|
m2 = -m2*m2;
|
||||||
|
mn = 1.;
|
||||||
|
for (unsigned int n = 2; n <= par().maxPow; n += 2)
|
||||||
|
{
|
||||||
|
Result r;
|
||||||
|
|
||||||
|
mn = mn*m2;
|
||||||
|
r.op = "tr(mag^" + std::to_string(n) + ")";
|
||||||
|
r.value = TensorRemove(trace(mn)).real();
|
||||||
|
result.push_back(r);
|
||||||
|
}
|
||||||
|
write(writer, "trmag", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MScalarSUN_TrMag_hpp_
|
182
extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp
Normal file
182
extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MScalarSUN_TrPhi_hpp_
|
||||||
|
#define Hadrons_MScalarSUN_TrPhi_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Module to compute tr(phi^n) *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MScalarSUN)
|
||||||
|
|
||||||
|
class TrPhiPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(TrPhiPar,
|
||||||
|
std::string, field,
|
||||||
|
unsigned int, maxPow,
|
||||||
|
std::string, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
class TTrPhi: public Module<TrPhiPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename SImpl::Field Field;
|
||||||
|
typedef typename SImpl::ComplexField ComplexField;
|
||||||
|
class Result: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||||
|
std::string, op,
|
||||||
|
Real, value);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TTrPhi(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TTrPhi(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);
|
||||||
|
private:
|
||||||
|
// output name generator
|
||||||
|
std::string outName(const unsigned int n);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(TrPhiSU2, TTrPhi<ScalarNxNAdjImplR<2>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrPhiSU3, TTrPhi<ScalarNxNAdjImplR<3>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrPhiSU4, TTrPhi<ScalarNxNAdjImplR<4>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrPhiSU5, TTrPhi<ScalarNxNAdjImplR<5>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TrPhiSU6, TTrPhi<ScalarNxNAdjImplR<6>>, MScalarSUN);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TTrPhi implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
TTrPhi<SImpl>::TTrPhi(const std::string name)
|
||||||
|
: Module<TrPhiPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TTrPhi<SImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().field};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TTrPhi<SImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out;
|
||||||
|
|
||||||
|
for (unsigned int n = 2; n <= par().maxPow; n += 2)
|
||||||
|
{
|
||||||
|
out.push_back(outName(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TTrPhi<SImpl>::setup(void)
|
||||||
|
{
|
||||||
|
if (par().maxPow < 2)
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Size, "'maxPow' should be at least equal to 2");
|
||||||
|
}
|
||||||
|
envTmpLat(Field, "phi2");
|
||||||
|
envTmpLat(Field, "buf");
|
||||||
|
for (unsigned int n = 2; n <= par().maxPow; n += 2)
|
||||||
|
{
|
||||||
|
envCreateLat(ComplexField, outName(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TTrPhi<SImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Computing tr(phi^n) for n even up to " << par().maxPow
|
||||||
|
<< "..." << std::endl;
|
||||||
|
|
||||||
|
std::vector<Result> result;
|
||||||
|
auto &phi = envGet(Field, par().field);
|
||||||
|
|
||||||
|
envGetTmp(Field, phi2);
|
||||||
|
envGetTmp(Field, buf);
|
||||||
|
buf = 1.;
|
||||||
|
phi2 = -phi*phi;
|
||||||
|
for (unsigned int n = 2; n <= par().maxPow; n += 2)
|
||||||
|
{
|
||||||
|
auto &phin = envGet(ComplexField, outName(n));
|
||||||
|
|
||||||
|
buf = buf*phi2;
|
||||||
|
phin = trace(buf);
|
||||||
|
if (!par().output.empty())
|
||||||
|
{
|
||||||
|
Result r;
|
||||||
|
|
||||||
|
r.op = "tr(phi^" + std::to_string(n) + ")";
|
||||||
|
r.value = TensorRemove(sum(phin)).real();
|
||||||
|
result.push_back(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.size() > 0)
|
||||||
|
{
|
||||||
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
|
|
||||||
|
write(writer, "trphi", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// output name generator ///////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
std::string TTrPhi<SImpl>::outName(const unsigned int n)
|
||||||
|
{
|
||||||
|
return getName() + "_" + std::to_string(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MScalarSUN_TrPhi_hpp_
|
184
extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp
Normal file
184
extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MScalarSUN_TwoPoint_hpp_
|
||||||
|
#define Hadrons_MScalarSUN_TwoPoint_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* 2-pt functions for a given set of operators *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MScalarSUN)
|
||||||
|
|
||||||
|
class TwoPointPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(TwoPointPar,
|
||||||
|
std::vector<std::string>, op,
|
||||||
|
std::string, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
class TTwoPoint: public Module<TwoPointPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename SImpl::Field Field;
|
||||||
|
typedef typename SImpl::ComplexField ComplexField;
|
||||||
|
class Result: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||||
|
std::string, sink,
|
||||||
|
std::string, source,
|
||||||
|
std::vector<Complex>, data);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TTwoPoint(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TTwoPoint(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);
|
||||||
|
private:
|
||||||
|
// make 2-pt function
|
||||||
|
template <class SinkSite, class SourceSite>
|
||||||
|
std::vector<Complex> makeTwoPoint(const std::vector<SinkSite> &sink,
|
||||||
|
const std::vector<SourceSite> &source);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(TwoPointSU2, TTwoPoint<ScalarNxNAdjImplR<2>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TwoPointSU3, TTwoPoint<ScalarNxNAdjImplR<3>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TwoPointSU4, TTwoPoint<ScalarNxNAdjImplR<4>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TwoPointSU5, TTwoPoint<ScalarNxNAdjImplR<5>>, MScalarSUN);
|
||||||
|
MODULE_REGISTER_NS(TwoPointSU6, TTwoPoint<ScalarNxNAdjImplR<6>>, MScalarSUN);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TTwoPoint implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
TTwoPoint<SImpl>::TTwoPoint(const std::string name)
|
||||||
|
: Module<TwoPointPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TTwoPoint<SImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
return par().op;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SImpl>
|
||||||
|
std::vector<std::string> TTwoPoint<SImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TTwoPoint<SImpl>::setup(void)
|
||||||
|
{
|
||||||
|
const unsigned int nt = env().getDim().back();
|
||||||
|
envTmp(std::vector<std::vector<TComplex>>, "slicedOp", 1, par().op.size(),
|
||||||
|
std::vector<TComplex>(nt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename SImpl>
|
||||||
|
void TTwoPoint<SImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Computing 2-point functions for operators:" << std::endl;
|
||||||
|
for (auto &o: par().op)
|
||||||
|
{
|
||||||
|
LOG(Message) << " '" << o << "'" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultWriter writer(RESULT_FILE_NAME(par().output));
|
||||||
|
const unsigned int nd = env().getDim().size();
|
||||||
|
std::vector<Result> result;
|
||||||
|
|
||||||
|
envGetTmp(std::vector<std::vector<TComplex>>, slicedOp);
|
||||||
|
for (unsigned int i = 0; i < par().op.size(); ++i)
|
||||||
|
{
|
||||||
|
auto &op = envGet(ComplexField, par().op[i]);
|
||||||
|
|
||||||
|
sliceSum(op, slicedOp[i], nd - 1);
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < par().op.size(); ++i)
|
||||||
|
for (unsigned int j = 0; j < par().op.size(); ++j)
|
||||||
|
{
|
||||||
|
Result r;
|
||||||
|
|
||||||
|
r.sink = par().op[i];
|
||||||
|
r.source = par().op[j];
|
||||||
|
r.data = makeTwoPoint(slicedOp[i], slicedOp[j]);
|
||||||
|
result.push_back(r);
|
||||||
|
}
|
||||||
|
write(writer, "twopt", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make 2-pt function //////////////////////////////////////////////////////////
|
||||||
|
template <class SImpl>
|
||||||
|
template <class SinkSite, class SourceSite>
|
||||||
|
std::vector<Complex> TTwoPoint<SImpl>::makeTwoPoint(
|
||||||
|
const std::vector<SinkSite> &sink,
|
||||||
|
const std::vector<SourceSite> &source)
|
||||||
|
{
|
||||||
|
assert(sink.size() == source.size());
|
||||||
|
|
||||||
|
unsigned int nt = sink.size();
|
||||||
|
std::vector<Complex> res(nt, 0.);
|
||||||
|
|
||||||
|
for (unsigned int dt = 0; dt < nt; ++dt)
|
||||||
|
{
|
||||||
|
for (unsigned int t = 0; t < nt; ++t)
|
||||||
|
{
|
||||||
|
res[dt] += TensorRemove(trace(sink[(t+dt)%nt]*source[t]));
|
||||||
|
}
|
||||||
|
res[dt] *= 1./static_cast<double>(nt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MScalarSUN_TwoPoint_hpp_
|
@ -1,3 +1,32 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSink/Point.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
#ifndef Hadrons_MSink_Point_hpp_
|
#ifndef Hadrons_MSink_Point_hpp_
|
||||||
#define Hadrons_MSink_Point_hpp_
|
#define Hadrons_MSink_Point_hpp_
|
||||||
|
|
||||||
@ -33,10 +62,14 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
|
private:
|
||||||
|
bool hasPhase_{false};
|
||||||
|
std::string momphName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(Point, TPoint<FIMPL>, MSink);
|
MODULE_REGISTER_NS(Point, TPoint<FIMPL>, MSink);
|
||||||
@ -49,6 +82,7 @@ MODULE_REGISTER_NS(ScalarPoint, TPoint<ScalarImplCR>, MSink);
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
TPoint<FImpl>::TPoint(const std::string name)
|
TPoint<FImpl>::TPoint(const std::string name)
|
||||||
: Module<PointPar>(name)
|
: Module<PointPar>(name)
|
||||||
|
, momphName_ (name + "_momph")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
@ -72,30 +106,37 @@ std::vector<std::string> TPoint<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPoint<FImpl>::setup(void)
|
void TPoint<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
envTmpLat(LatticeComplex, "coor");
|
||||||
|
envCacheLat(LatticeComplex, momphName_);
|
||||||
size = env().template lattice4dSize<LatticeComplex>();
|
envCreate(SinkFn, getName(), 1, nullptr);
|
||||||
env().registerObject(getName(), size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPoint<FImpl>::execute(void)
|
void TPoint<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
std::vector<Real> p = strToVec<Real>(par().mom);
|
|
||||||
LatticeComplex ph(env().getGrid()), coor(env().getGrid());
|
|
||||||
Complex i(0.0,1.0);
|
|
||||||
|
|
||||||
LOG(Message) << "Setting up point sink function for momentum ["
|
LOG(Message) << "Setting up point sink function for momentum ["
|
||||||
<< par().mom << "]" << std::endl;
|
<< par().mom << "]" << std::endl;
|
||||||
ph = zero;
|
|
||||||
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
auto &ph = envGet(LatticeComplex, momphName_);
|
||||||
|
|
||||||
|
if (!hasPhase_)
|
||||||
{
|
{
|
||||||
LatticeCoordinate(coor, mu);
|
Complex i(0.0,1.0);
|
||||||
ph = ph + (p[mu]/env().getGrid()->_fdimensions[mu])*coor;
|
std::vector<Real> p;
|
||||||
|
|
||||||
|
envGetTmp(LatticeComplex, coor);
|
||||||
|
p = strToVec<Real>(par().mom);
|
||||||
|
ph = zero;
|
||||||
|
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
||||||
|
{
|
||||||
|
LatticeCoordinate(coor, mu);
|
||||||
|
ph = ph + (p[mu]/env().getGrid()->_fdimensions[mu])*coor;
|
||||||
|
}
|
||||||
|
ph = exp((Real)(2*M_PI)*i*ph);
|
||||||
|
hasPhase_ = true;
|
||||||
}
|
}
|
||||||
ph = exp((Real)(2*M_PI)*i*ph);
|
auto sink = [&ph](const PropagatorField &field)
|
||||||
auto sink = [ph](const PropagatorField &field)
|
|
||||||
{
|
{
|
||||||
SlicedPropagator res;
|
SlicedPropagator res;
|
||||||
PropagatorField tmp = ph*field;
|
PropagatorField tmp = ph*field;
|
||||||
@ -104,7 +145,7 @@ void TPoint<FImpl>::execute(void)
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
env().setObject(getName(), new SinkFn(sink));
|
envGet(SinkFn, getName()) = sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
127
extras/Hadrons/Modules/MSink/Smear.hpp
Normal file
127
extras/Hadrons/Modules/MSink/Smear.hpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSink/Smear.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_MSink_Smear_hpp_
|
||||||
|
#define Hadrons_MSink_Smear_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Smear *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSink)
|
||||||
|
|
||||||
|
class SmearPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(SmearPar,
|
||||||
|
std::string, q,
|
||||||
|
std::string, sink);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TSmear: public Module<SmearPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FERM_TYPE_ALIASES(FImpl,);
|
||||||
|
SINK_TYPE_ALIASES();
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TSmear(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TSmear(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Smear, TSmear<FIMPL>, MSink);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TSmear implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TSmear<FImpl>::TSmear(const std::string name)
|
||||||
|
: Module<SmearPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TSmear<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().q, par().sink};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TSmear<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TSmear<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
envCreate(SlicedPropagator, getName(), 1, env().getDim(Tp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TSmear<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Sink smearing propagator '" << par().q
|
||||||
|
<< "' using sink function '" << par().sink << "'."
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
auto &sink = envGet(SinkFn, par().sink);
|
||||||
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
|
auto &out = envGet(SlicedPropagator, getName());
|
||||||
|
|
||||||
|
out = sink(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MSink_Smear_hpp_
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
|
Source file: extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -61,7 +60,9 @@ public:
|
|||||||
virtual ~TRBPrecCG(void) = default;
|
virtual ~TRBPrecCG(void) = default;
|
||||||
// dependencies/products
|
// dependencies/products
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getReference(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -83,11 +84,19 @@ TRBPrecCG<FImpl>::TRBPrecCG(const std::string name)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TRBPrecCG<FImpl>::getInput(void)
|
std::vector<std::string> TRBPrecCG<FImpl>::getInput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> in = {par().action};
|
std::vector<std::string> in = {};
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TRBPrecCG<FImpl>::getReference(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> ref = {par().action};
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void)
|
std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void)
|
||||||
{
|
{
|
||||||
@ -100,17 +109,12 @@ std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TRBPrecCG<FImpl>::setup(void)
|
void TRBPrecCG<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
auto Ls = env().getObjectLs(par().action);
|
LOG(Message) << "setting up Schur red-black preconditioned CG for"
|
||||||
|
<< " action '" << par().action << "' with residual "
|
||||||
|
<< par().residual << std::endl;
|
||||||
|
|
||||||
env().registerObject(getName(), 0, Ls);
|
auto Ls = env().getObjectLs(par().action);
|
||||||
env().addOwnership(getName(), par().action);
|
auto &mat = envGet(FMat, par().action);
|
||||||
}
|
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
|
||||||
template <typename FImpl>
|
|
||||||
void TRBPrecCG<FImpl>::execute(void)
|
|
||||||
{
|
|
||||||
auto &mat = *(env().template getObject<FMat>(par().action));
|
|
||||||
auto solver = [&mat, this](FermionField &sol, const FermionField &source)
|
auto solver = [&mat, this](FermionField &sol, const FermionField &source)
|
||||||
{
|
{
|
||||||
ConjugateGradient<FermionField> cg(par().residual, 10000);
|
ConjugateGradient<FermionField> cg(par().residual, 10000);
|
||||||
@ -118,13 +122,14 @@ void TRBPrecCG<FImpl>::execute(void)
|
|||||||
|
|
||||||
schurSolver(mat, source, sol);
|
schurSolver(mat, source, sol);
|
||||||
};
|
};
|
||||||
|
envCreate(SolverFn, getName(), Ls, solver);
|
||||||
LOG(Message) << "setting up Schur red-black preconditioned CG for"
|
|
||||||
<< " action '" << par().action << "' with residual "
|
|
||||||
<< par().residual << std::endl;
|
|
||||||
env().setObject(getName(), new SolverFn(solver));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TRBPrecCG<FImpl>::execute(void)
|
||||||
|
{}
|
||||||
|
|
||||||
END_MODULE_NAMESPACE
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
@ -4,10 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MSource/Point.hpp
|
Source file: extras/Hadrons/Modules/MSource/Point.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -72,6 +72,7 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
@ -111,19 +112,20 @@ std::vector<std::string> TPoint<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPoint<FImpl>::setup(void)
|
void TPoint<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
envCreateLat(PropagatorField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TPoint<FImpl>::execute(void)
|
void TPoint<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
std::vector<int> position = strToVec<int>(par().position);
|
|
||||||
typename SitePropagator::scalar_object id;
|
|
||||||
|
|
||||||
LOG(Message) << "Creating point source at position [" << par().position
|
LOG(Message) << "Creating point source at position [" << par().position
|
||||||
<< "]" << std::endl;
|
<< "]" << std::endl;
|
||||||
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
|
||||||
|
std::vector<int> position = strToVec<int>(par().position);
|
||||||
|
auto &src = envGet(PropagatorField, getName());
|
||||||
|
SitePropagator id;
|
||||||
|
|
||||||
id = 1.;
|
id = 1.;
|
||||||
src = zero;
|
src = zero;
|
||||||
pokeSite(id, src, position);
|
pokeSite(id, src, position);
|
||||||
|
160
extras/Hadrons/Modules/MSource/SeqConserved.hpp
Normal file
160
extras/Hadrons/Modules/MSource/SeqConserved.hpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSource/SeqConserved.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_MSource_SeqConserved_hpp_
|
||||||
|
#define Hadrons_MSource_SeqConserved_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Sequential source
|
||||||
|
-----------------------------
|
||||||
|
* src_x = q_x * theta(x_3 - tA) * theta(tB - x_3) * J_mu * exp(i x.mom)
|
||||||
|
|
||||||
|
* options:
|
||||||
|
- q: input propagator (string)
|
||||||
|
- action: fermion action used for propagator q (string)
|
||||||
|
- tA: begin timeslice (integer)
|
||||||
|
- tB: end timesilce (integer)
|
||||||
|
- curr_type: type of conserved current to insert (Current)
|
||||||
|
- mu: Lorentz index of current to insert (integer)
|
||||||
|
- mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0.")
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* SeqConserved *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSource)
|
||||||
|
|
||||||
|
class SeqConservedPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(SeqConservedPar,
|
||||||
|
std::string, q,
|
||||||
|
std::string, action,
|
||||||
|
unsigned int, tA,
|
||||||
|
unsigned int, tB,
|
||||||
|
Current, curr_type,
|
||||||
|
unsigned int, mu,
|
||||||
|
std::string, mom);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TSeqConserved: public Module<SeqConservedPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FERM_TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TSeqConserved(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TSeqConserved(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(SeqConserved, TSeqConserved<FIMPL>, MSource);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TSeqConserved implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TSeqConserved<FImpl>::TSeqConserved(const std::string name)
|
||||||
|
: Module<SeqConservedPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TSeqConserved<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().q, par().action};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TSeqConserved<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TSeqConserved<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
auto Ls_ = env().getObjectLs(par().action);
|
||||||
|
envCreateLat(PropagatorField, getName(), Ls_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TSeqConserved<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
if (par().tA == par().tB)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating sequential source with conserved "
|
||||||
|
<< par().curr_type << " current insertion (mu = "
|
||||||
|
<< par().mu << ") at " << "t = " << par().tA << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating sequential source with conserved "
|
||||||
|
<< par().curr_type << " current insertion (mu = "
|
||||||
|
<< par().mu << ") for " << par().tA << " <= t <= "
|
||||||
|
<< par().tB << std::endl;
|
||||||
|
}
|
||||||
|
auto &src = envGet(PropagatorField, getName());
|
||||||
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
|
auto &mat = envGet(FMat, par().action);
|
||||||
|
|
||||||
|
std::vector<Real> mom = strToVec<Real>(par().mom);
|
||||||
|
mat.SeqConservedCurrent(q, src, par().curr_type, par().mu,
|
||||||
|
mom, par().tA, par().tB);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_SeqConserved_hpp_
|
@ -4,11 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MSource/SeqGamma.hpp
|
Source file: extras/Hadrons/Modules/MSource/SeqGamma.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
Copyright (C) 2017
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -81,10 +80,14 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
|
private:
|
||||||
|
bool hasPhase_{false};
|
||||||
|
std::string momphName_, tName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(SeqGamma, TSeqGamma<FIMPL>, MSource);
|
MODULE_REGISTER_NS(SeqGamma, TSeqGamma<FIMPL>, MSource);
|
||||||
@ -96,6 +99,8 @@ MODULE_REGISTER_NS(SeqGamma, TSeqGamma<FIMPL>, MSource);
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
TSeqGamma<FImpl>::TSeqGamma(const std::string name)
|
TSeqGamma<FImpl>::TSeqGamma(const std::string name)
|
||||||
: Module<SeqGammaPar>(name)
|
: Module<SeqGammaPar>(name)
|
||||||
|
, momphName_ (name + "_momph")
|
||||||
|
, tName_ (name + "_t")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
@ -119,7 +124,10 @@ std::vector<std::string> TSeqGamma<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TSeqGamma<FImpl>::setup(void)
|
void TSeqGamma<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
envCreateLat(PropagatorField, getName());
|
||||||
|
envCacheLat(Lattice<iScalar<vInteger>>, tName_);
|
||||||
|
envCacheLat(LatticeComplex, momphName_);
|
||||||
|
envTmpLat(LatticeComplex, "coor");
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -137,23 +145,29 @@ void TSeqGamma<FImpl>::execute(void)
|
|||||||
<< " sequential source for "
|
<< " sequential source for "
|
||||||
<< par().tA << " <= t <= " << par().tB << std::endl;
|
<< par().tA << " <= t <= " << par().tB << std::endl;
|
||||||
}
|
}
|
||||||
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
auto &src = envGet(PropagatorField, getName());
|
||||||
PropagatorField &q = *env().template getObject<PropagatorField>(par().q);
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
Lattice<iScalar<vInteger>> t(env().getGrid());
|
auto &ph = envGet(LatticeComplex, momphName_);
|
||||||
LatticeComplex ph(env().getGrid()), coor(env().getGrid());
|
auto &t = envGet(Lattice<iScalar<vInteger>>, tName_);
|
||||||
Gamma g(par().gamma);
|
Gamma g(par().gamma);
|
||||||
std::vector<Real> p;
|
|
||||||
Complex i(0.0,1.0);
|
|
||||||
|
|
||||||
p = strToVec<Real>(par().mom);
|
if (!hasPhase_)
|
||||||
ph = zero;
|
|
||||||
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
|
||||||
{
|
{
|
||||||
LatticeCoordinate(coor, mu);
|
Complex i(0.0,1.0);
|
||||||
ph = ph + p[mu]*coor*((1./(env().getGrid()->_fdimensions[mu])));
|
std::vector<Real> p;
|
||||||
|
|
||||||
|
envGetTmp(LatticeComplex, coor);
|
||||||
|
p = strToVec<Real>(par().mom);
|
||||||
|
ph = zero;
|
||||||
|
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
||||||
|
{
|
||||||
|
LatticeCoordinate(coor, mu);
|
||||||
|
ph = ph + (p[mu]/env().getGrid()->_fdimensions[mu])*coor;
|
||||||
|
}
|
||||||
|
ph = exp((Real)(2*M_PI)*i*ph);
|
||||||
|
LatticeCoordinate(t, Tp);
|
||||||
|
hasPhase_ = true;
|
||||||
}
|
}
|
||||||
ph = exp((Real)(2*M_PI)*i*ph);
|
|
||||||
LatticeCoordinate(t, Tp);
|
|
||||||
src = where((t >= par().tA) and (t <= par().tB), ph*(g*q), 0.*q);
|
src = where((t >= par().tA) and (t <= par().tB), ph*(g*q), 0.*q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MSource/Wall.hpp
|
Source file: extras/Hadrons/Modules/MSource/Wall.hpp
|
||||||
|
|
||||||
Copyright (C) 2017
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -73,10 +74,14 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
|
private:
|
||||||
|
bool hasPhase_{false};
|
||||||
|
std::string momphName_, tName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(Wall, TWall<FIMPL>, MSource);
|
MODULE_REGISTER_NS(Wall, TWall<FIMPL>, MSource);
|
||||||
@ -88,13 +93,15 @@ MODULE_REGISTER_NS(Wall, TWall<FIMPL>, MSource);
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
TWall<FImpl>::TWall(const std::string name)
|
TWall<FImpl>::TWall(const std::string name)
|
||||||
: Module<WallPar>(name)
|
: Module<WallPar>(name)
|
||||||
|
, momphName_ (name + "_momph")
|
||||||
|
, tName_ (name + "_t")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
std::vector<std::string> TWall<FImpl>::getInput(void)
|
std::vector<std::string> TWall<FImpl>::getInput(void)
|
||||||
{
|
{
|
||||||
std::vector<std::string> in;
|
std::vector<std::string> in = {};
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
@ -111,7 +118,7 @@ std::vector<std::string> TWall<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TWall<FImpl>::setup(void)
|
void TWall<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
envCreateLat(PropagatorField, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
@ -121,21 +128,28 @@ void TWall<FImpl>::execute(void)
|
|||||||
LOG(Message) << "Generating wall source at t = " << par().tW
|
LOG(Message) << "Generating wall source at t = " << par().tW
|
||||||
<< " with momentum " << par().mom << std::endl;
|
<< " with momentum " << par().mom << std::endl;
|
||||||
|
|
||||||
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
auto &src = envGet(PropagatorField, getName());
|
||||||
Lattice<iScalar<vInteger>> t(env().getGrid());
|
auto &ph = envGet(LatticeComplex, momphName_);
|
||||||
LatticeComplex ph(env().getGrid()), coor(env().getGrid());
|
auto &t = envGet(Lattice<iScalar<vInteger>>, tName_);
|
||||||
std::vector<Real> p;
|
|
||||||
Complex i(0.0,1.0);
|
|
||||||
|
|
||||||
p = strToVec<Real>(par().mom);
|
if (!hasPhase_)
|
||||||
ph = zero;
|
|
||||||
for(unsigned int mu = 0; mu < Nd; mu++)
|
|
||||||
{
|
{
|
||||||
LatticeCoordinate(coor, mu);
|
Complex i(0.0,1.0);
|
||||||
ph = ph + p[mu]*coor*((1./(env().getGrid()->_fdimensions[mu])));
|
std::vector<Real> p;
|
||||||
|
|
||||||
|
envGetTmp(LatticeComplex, coor);
|
||||||
|
p = strToVec<Real>(par().mom);
|
||||||
|
ph = zero;
|
||||||
|
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
||||||
|
{
|
||||||
|
LatticeCoordinate(coor, mu);
|
||||||
|
ph = ph + (p[mu]/env().getGrid()->_fdimensions[mu])*coor;
|
||||||
|
}
|
||||||
|
ph = exp((Real)(2*M_PI)*i*ph);
|
||||||
|
LatticeCoordinate(t, Tp);
|
||||||
|
hasPhase_ = true;
|
||||||
}
|
}
|
||||||
ph = exp((Real)(2*M_PI)*i*ph);
|
|
||||||
LatticeCoordinate(t, Tp);
|
|
||||||
src = 1.;
|
src = 1.;
|
||||||
src = where((t == par().tW), src*ph, 0.*src);
|
src = where((t == par().tW), src*ph, 0.*src);
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
|
|||||||
|
|
||||||
Source file: extras/Hadrons/Modules/MSource/Z2.hpp
|
Source file: extras/Hadrons/Modules/MSource/Z2.hpp
|
||||||
|
|
||||||
Copyright (C) 2015
|
Copyright (C) 2015-2018
|
||||||
Copyright (C) 2016
|
|
||||||
|
|
||||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
@ -76,10 +75,14 @@ public:
|
|||||||
// dependency relation
|
// dependency relation
|
||||||
virtual std::vector<std::string> getInput(void);
|
virtual std::vector<std::string> getInput(void);
|
||||||
virtual std::vector<std::string> getOutput(void);
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
// setup
|
// setup
|
||||||
virtual void setup(void);
|
virtual void setup(void);
|
||||||
// execution
|
// execution
|
||||||
virtual void execute(void);
|
virtual void execute(void);
|
||||||
|
private:
|
||||||
|
bool hasT_{false};
|
||||||
|
std::string tName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_REGISTER_NS(Z2, TZ2<FIMPL>, MSource);
|
MODULE_REGISTER_NS(Z2, TZ2<FIMPL>, MSource);
|
||||||
@ -92,6 +95,7 @@ MODULE_REGISTER_NS(ScalarZ2, TZ2<ScalarImplCR>, MSource);
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
TZ2<FImpl>::TZ2(const std::string name)
|
TZ2<FImpl>::TZ2(const std::string name)
|
||||||
: Module<Z2Par>(name)
|
: Module<Z2Par>(name)
|
||||||
|
, tName_ (name + "_t")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// dependencies/products ///////////////////////////////////////////////////////
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
@ -115,29 +119,36 @@ std::vector<std::string> TZ2<FImpl>::getOutput(void)
|
|||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TZ2<FImpl>::setup(void)
|
void TZ2<FImpl>::setup(void)
|
||||||
{
|
{
|
||||||
env().template registerLattice<PropagatorField>(getName());
|
envCreateLat(PropagatorField, getName());
|
||||||
|
envCacheLat(Lattice<iScalar<vInteger>>, tName_);
|
||||||
|
envTmpLat(LatticeComplex, "eta");
|
||||||
}
|
}
|
||||||
|
|
||||||
// execution ///////////////////////////////////////////////////////////////////
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
template <typename FImpl>
|
template <typename FImpl>
|
||||||
void TZ2<FImpl>::execute(void)
|
void TZ2<FImpl>::execute(void)
|
||||||
{
|
{
|
||||||
Lattice<iScalar<vInteger>> t(env().getGrid());
|
|
||||||
LatticeComplex eta(env().getGrid());
|
|
||||||
Complex shift(1., 1.);
|
|
||||||
|
|
||||||
if (par().tA == par().tB)
|
if (par().tA == par().tB)
|
||||||
{
|
{
|
||||||
LOG(Message) << "Generating Z_2 wall source at t= " << par().tA
|
LOG(Message) << "Generating Z_2 wall source at t= " << par().tA
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(Message) << "Generating Z_2 band for " << par().tA << " <= t <= "
|
LOG(Message) << "Generating Z_2 band for " << par().tA << " <= t <= "
|
||||||
<< par().tB << std::endl;
|
<< par().tB << std::endl;
|
||||||
}
|
}
|
||||||
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
|
||||||
LatticeCoordinate(t, Tp);
|
auto &src = envGet(PropagatorField, getName());
|
||||||
|
auto &t = envGet(Lattice<iScalar<vInteger>>, tName_);
|
||||||
|
Complex shift(1., 1.);
|
||||||
|
|
||||||
|
if (!hasT_)
|
||||||
|
{
|
||||||
|
LatticeCoordinate(t, Tp);
|
||||||
|
hasT_ = true;
|
||||||
|
}
|
||||||
|
envGetTmp(LatticeComplex, eta);
|
||||||
bernoulli(*env().get4dRng(), eta);
|
bernoulli(*env().get4dRng(), eta);
|
||||||
eta = (2.*eta - shift)*(1./::sqrt(2.));
|
eta = (2.*eta - shift)*(1./::sqrt(2.));
|
||||||
eta = where((t >= par().tA) and (t <= par().tB), eta, 0.*eta);
|
eta = where((t >= par().tA) and (t <= par().tB), eta, 0.*eta);
|
||||||
|
186
extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp
Normal file
186
extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_MUtilities_TestSeqConserved_hpp_
|
||||||
|
#define Hadrons_MUtilities_TestSeqConserved_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ward Identity contractions using sequential propagators.
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
* options:
|
||||||
|
- q: point source propagator, 5D if available (string)
|
||||||
|
- qSeq: result of sequential insertion of conserved current using q (string)
|
||||||
|
- action: action used for computation of q (string)
|
||||||
|
- origin: string giving point source origin of q (string)
|
||||||
|
- t_J: time at which sequential current is inserted (int)
|
||||||
|
- mu: Lorentz index of current inserted (int)
|
||||||
|
- curr: current type, e.g. vector/axial (Current)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TestSeqConserved *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MUtilities)
|
||||||
|
|
||||||
|
class TestSeqConservedPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(TestSeqConservedPar,
|
||||||
|
std::string, q,
|
||||||
|
std::string, qSeq,
|
||||||
|
std::string, action,
|
||||||
|
std::string, origin,
|
||||||
|
unsigned int, t_J,
|
||||||
|
unsigned int, mu,
|
||||||
|
Current, curr);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TTestSeqConserved: public Module<TestSeqConservedPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FERM_TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TTestSeqConserved(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TTestSeqConserved(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(TestSeqConserved, TTestSeqConserved<FIMPL>, MUtilities);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TTestSeqConserved implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TTestSeqConserved<FImpl>::TTestSeqConserved(const std::string name)
|
||||||
|
: Module<TestSeqConservedPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TTestSeqConserved<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().q, par().qSeq, par().action};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TTestSeqConserved<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TTestSeqConserved<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
auto Ls = env().getObjectLs(par().q);
|
||||||
|
if (Ls != env().getObjectLs(par().action))
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Size, "Ls mismatch between quark action and propagator");
|
||||||
|
}
|
||||||
|
envTmpLat(PropagatorField, "tmp");
|
||||||
|
envTmpLat(LatticeComplex, "c");
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TTestSeqConserved<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
// Check sequential insertion of current gives same result as conserved
|
||||||
|
// current sink upon contraction. Assume q uses a point source.
|
||||||
|
|
||||||
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
|
auto &qSeq = envGet(PropagatorField, par().qSeq);
|
||||||
|
auto &act = envGet(FMat, par().action);
|
||||||
|
Gamma g5(Gamma::Algebra::Gamma5);
|
||||||
|
Gamma::Algebra gA = (par().curr == Current::Axial) ?
|
||||||
|
Gamma::Algebra::Gamma5 :
|
||||||
|
Gamma::Algebra::Identity;
|
||||||
|
Gamma g(gA);
|
||||||
|
SitePropagator qSite;
|
||||||
|
Complex test_S, test_V, check_S, check_V;
|
||||||
|
std::vector<TComplex> check_buf;
|
||||||
|
std::vector<int> siteCoord;
|
||||||
|
|
||||||
|
envGetTmp(PropagatorField, tmp);
|
||||||
|
envGetTmp(LatticeComplex, c);
|
||||||
|
siteCoord = strToVec<int>(par().origin);
|
||||||
|
peekSite(qSite, qSeq, siteCoord);
|
||||||
|
test_S = trace(qSite*g);
|
||||||
|
test_V = trace(qSite*g*Gamma::gmu[par().mu]);
|
||||||
|
act.ContractConservedCurrent(q, q, tmp, par().curr, par().mu);
|
||||||
|
c = trace(tmp*g);
|
||||||
|
sliceSum(c, check_buf, Tp);
|
||||||
|
check_S = TensorRemove(check_buf[par().t_J]);
|
||||||
|
|
||||||
|
c = trace(tmp*g*Gamma::gmu[par().mu]);
|
||||||
|
sliceSum(c, check_buf, Tp);
|
||||||
|
check_V = TensorRemove(check_buf[par().t_J]);
|
||||||
|
|
||||||
|
LOG(Message) << "Test S = " << abs(test_S) << std::endl;
|
||||||
|
LOG(Message) << "Test V = " << abs(test_V) << std::endl;
|
||||||
|
LOG(Message) << "Check S = " << abs(check_S) << std::endl;
|
||||||
|
LOG(Message) << "Check V = " << abs(check_V) << std::endl;
|
||||||
|
|
||||||
|
// Check difference = 0
|
||||||
|
check_S -= test_S;
|
||||||
|
check_V -= test_V;
|
||||||
|
|
||||||
|
LOG(Message) << "Consistency check for sequential conserved "
|
||||||
|
<< par().curr << " current insertion: " << std::endl;
|
||||||
|
LOG(Message) << "Diff S = " << abs(check_S) << std::endl;
|
||||||
|
LOG(Message) << "Diff V = " << abs(check_V) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_TestSeqConserved_hpp_
|
150
extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp
Normal file
150
extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
Author: Lanny91 <andrew.lawson@gmail.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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_MUtilities_TestSeqGamma_hpp_
|
||||||
|
#define Hadrons_MUtilities_TestSeqGamma_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TestSeqGamma *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MUtilities)
|
||||||
|
|
||||||
|
class TestSeqGammaPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(TestSeqGammaPar,
|
||||||
|
std::string, q,
|
||||||
|
std::string, qSeq,
|
||||||
|
std::string, origin,
|
||||||
|
Gamma::Algebra, gamma,
|
||||||
|
unsigned int, t_g);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TTestSeqGamma: public Module<TestSeqGammaPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FERM_TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TTestSeqGamma(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TTestSeqGamma(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
protected:
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(TestSeqGamma, TTestSeqGamma<FIMPL>, MUtilities);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TTestSeqGamma implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TTestSeqGamma<FImpl>::TTestSeqGamma(const std::string name)
|
||||||
|
: Module<TestSeqGammaPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TTestSeqGamma<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().q, par().qSeq};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TTestSeqGamma<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TTestSeqGamma<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
envTmpLat(LatticeComplex, "c");
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TTestSeqGamma<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
auto &q = envGet(PropagatorField, par().q);
|
||||||
|
auto &qSeq = envGet(PropagatorField, par().qSeq);
|
||||||
|
Gamma g5(Gamma::Algebra::Gamma5);
|
||||||
|
Gamma g(par().gamma);
|
||||||
|
SitePropagator qSite;
|
||||||
|
Complex test, check;
|
||||||
|
std::vector<TComplex> check_buf;
|
||||||
|
std::vector<int> siteCoord;
|
||||||
|
|
||||||
|
// Check sequential insertion of gamma matrix gives same result as
|
||||||
|
// insertion of gamma at sink upon contraction. Assume q uses a point
|
||||||
|
// source.
|
||||||
|
|
||||||
|
envGetTmp(LatticeComplex, c);
|
||||||
|
siteCoord = strToVec<int>(par().origin);
|
||||||
|
peekSite(qSite, qSeq, siteCoord);
|
||||||
|
test = trace(g*qSite);
|
||||||
|
|
||||||
|
c = trace(adj(g)*g5*adj(q)*g5*g*q);
|
||||||
|
sliceSum(c, check_buf, Tp);
|
||||||
|
check = TensorRemove(check_buf[par().t_g]);
|
||||||
|
|
||||||
|
LOG(Message) << "Seq Result = " << abs(test) << std::endl;
|
||||||
|
LOG(Message) << "Reference = " << abs(check) << std::endl;
|
||||||
|
|
||||||
|
// Check difference = 0
|
||||||
|
check -= test;
|
||||||
|
|
||||||
|
LOG(Message) << "Consistency check for sequential " << par().gamma
|
||||||
|
<< " insertion = " << abs(check) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_TestSeqGamma_hpp_
|
622
extras/Hadrons/VirtualMachine.cc
Normal file
622
extras/Hadrons/VirtualMachine.cc
Normal file
@ -0,0 +1,622 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/VirtualMachine.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/VirtualMachine.hpp>
|
||||||
|
#include <Grid/Hadrons/GeneticScheduler.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* VirtualMachine implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// trajectory counter //////////////////////////////////////////////////////////
|
||||||
|
void VirtualMachine::setTrajectory(const unsigned int traj)
|
||||||
|
{
|
||||||
|
traj_ = traj;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int VirtualMachine::getTrajectory(void) const
|
||||||
|
{
|
||||||
|
return traj_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// module management ///////////////////////////////////////////////////////////
|
||||||
|
void VirtualMachine::pushModule(VirtualMachine::ModPt &pt)
|
||||||
|
{
|
||||||
|
std::string name = pt->getName();
|
||||||
|
|
||||||
|
if (!hasModule(name))
|
||||||
|
{
|
||||||
|
std::vector<unsigned int> inputAddress;
|
||||||
|
unsigned int address;
|
||||||
|
ModuleInfo m;
|
||||||
|
|
||||||
|
// module registration -------------------------------------------------
|
||||||
|
m.data = std::move(pt);
|
||||||
|
m.type = typeIdPt(*m.data.get());
|
||||||
|
m.name = name;
|
||||||
|
// input dependencies
|
||||||
|
for (auto &in: m.data->getInput())
|
||||||
|
{
|
||||||
|
if (!env().hasObject(in))
|
||||||
|
{
|
||||||
|
// if object does not exist, add it with no creator module
|
||||||
|
env().addObject(in , -1);
|
||||||
|
}
|
||||||
|
m.input.push_back(env().getObjectAddress(in));
|
||||||
|
}
|
||||||
|
// reference dependencies
|
||||||
|
for (auto &ref: m.data->getReference())
|
||||||
|
{
|
||||||
|
if (!env().hasObject(ref))
|
||||||
|
{
|
||||||
|
// if object does not exist, add it with no creator module
|
||||||
|
env().addObject(ref , -1);
|
||||||
|
}
|
||||||
|
m.input.push_back(env().getObjectAddress(ref));
|
||||||
|
}
|
||||||
|
auto inCopy = m.input;
|
||||||
|
// if module has inputs with references, they need to be added as
|
||||||
|
// an input
|
||||||
|
for (auto &in: inCopy)
|
||||||
|
{
|
||||||
|
int inm = env().getObjectModule(in);
|
||||||
|
|
||||||
|
if (inm > 0)
|
||||||
|
{
|
||||||
|
if (getModule(inm)->getReference().size() > 0)
|
||||||
|
{
|
||||||
|
for (auto &rin: getModule(inm)->getReference())
|
||||||
|
{
|
||||||
|
m.input.push_back(env().getObjectAddress(rin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module_.push_back(std::move(m));
|
||||||
|
address = static_cast<unsigned int>(module_.size() - 1);
|
||||||
|
moduleAddress_[name] = address;
|
||||||
|
// connecting outputs to potential inputs ------------------------------
|
||||||
|
for (auto &out: getModule(address)->getOutput())
|
||||||
|
{
|
||||||
|
if (!env().hasObject(out))
|
||||||
|
{
|
||||||
|
// output does not exists, add it
|
||||||
|
env().addObject(out, address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (env().getObjectModule(env().getObjectAddress(out)) < 0)
|
||||||
|
{
|
||||||
|
// output exists but without creator, correct it
|
||||||
|
env().setObjectModule(env().getObjectAddress(out), address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// output already fully registered, error
|
||||||
|
HADRON_ERROR(Definition, "object '" + out
|
||||||
|
+ "' is already produced by module '"
|
||||||
|
+ module_[env().getObjectModule(out)].name
|
||||||
|
+ "' (while pushing module '" + name + "')");
|
||||||
|
}
|
||||||
|
if (getModule(address)->getReference().size() > 0)
|
||||||
|
{
|
||||||
|
// module has references, dependency should be propagated
|
||||||
|
// to children modules; find module with `out` as an input
|
||||||
|
// and add references to their input
|
||||||
|
auto pred = [this, out](const ModuleInfo &n)
|
||||||
|
{
|
||||||
|
auto &in = n.input;
|
||||||
|
auto it = std::find(in.begin(), in.end(),
|
||||||
|
env().getObjectAddress(out));
|
||||||
|
|
||||||
|
return (it != in.end());
|
||||||
|
};
|
||||||
|
auto it = std::find_if(module_.begin(), module_.end(), pred);
|
||||||
|
while (it != module_.end())
|
||||||
|
{
|
||||||
|
for (auto &ref: getModule(address)->getReference())
|
||||||
|
{
|
||||||
|
it->input.push_back(env().getObjectAddress(ref));
|
||||||
|
}
|
||||||
|
it = std::find_if(++it, module_.end(), pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graphOutdated_ = true;
|
||||||
|
memoryProfileOutdated_ = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "module '" + name + "' already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int VirtualMachine::getNModule(void) const
|
||||||
|
{
|
||||||
|
return module_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::createModule(const std::string name, const std::string type,
|
||||||
|
XmlReader &reader)
|
||||||
|
{
|
||||||
|
auto &factory = ModuleFactory::getInstance();
|
||||||
|
auto pt = factory.create(type, name);
|
||||||
|
|
||||||
|
pt->parseParameters(reader, "options");
|
||||||
|
pushModule(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleBase * VirtualMachine::getModule(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasModule(address))
|
||||||
|
{
|
||||||
|
return module_[address].data.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "no module with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleBase * VirtualMachine::getModule(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModule(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int VirtualMachine::getModuleAddress(const std::string name) const
|
||||||
|
{
|
||||||
|
if (hasModule(name))
|
||||||
|
{
|
||||||
|
return moduleAddress_.at(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "no module with name '" + name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VirtualMachine::getModuleName(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasModule(address))
|
||||||
|
{
|
||||||
|
return module_[address].name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "no module with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VirtualMachine::getModuleType(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasModule(address))
|
||||||
|
{
|
||||||
|
return typeName(module_[address].type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "no module with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VirtualMachine::getModuleType(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModuleType(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VirtualMachine::getModuleNamespace(const unsigned int address) const
|
||||||
|
{
|
||||||
|
std::string type = getModuleType(address), ns;
|
||||||
|
|
||||||
|
auto pos2 = type.rfind("::");
|
||||||
|
auto pos1 = type.rfind("::", pos2 - 2);
|
||||||
|
|
||||||
|
return type.substr(pos1 + 2, pos2 - pos1 - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VirtualMachine::getModuleNamespace(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModuleNamespace(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMachine::hasModule(const unsigned int address) const
|
||||||
|
{
|
||||||
|
return (address < module_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMachine::hasModule(const std::string name) const
|
||||||
|
{
|
||||||
|
return (moduleAddress_.find(name) != moduleAddress_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// print VM content ////////////////////////////////////////////////////////////
|
||||||
|
void VirtualMachine::printContent(void) const
|
||||||
|
{
|
||||||
|
LOG(Debug) << "Modules: " << std::endl;
|
||||||
|
for (unsigned int i = 0; i < module_.size(); ++i)
|
||||||
|
{
|
||||||
|
LOG(Debug) << std::setw(4) << i << ": "
|
||||||
|
<< getModuleName(i) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// module graph ////////////////////////////////////////////////////////////////
|
||||||
|
Graph<unsigned int> VirtualMachine::getModuleGraph(void)
|
||||||
|
{
|
||||||
|
if (graphOutdated_)
|
||||||
|
{
|
||||||
|
makeModuleGraph();
|
||||||
|
graphOutdated_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::makeModuleGraph(void)
|
||||||
|
{
|
||||||
|
Graph<unsigned int> graph;
|
||||||
|
|
||||||
|
// create vertices
|
||||||
|
for (unsigned int m = 0; m < module_.size(); ++m)
|
||||||
|
{
|
||||||
|
graph.addVertex(m);
|
||||||
|
}
|
||||||
|
// create edges
|
||||||
|
for (unsigned int m = 0; m < module_.size(); ++m)
|
||||||
|
{
|
||||||
|
for (auto &in: module_[m].input)
|
||||||
|
{
|
||||||
|
graph.addEdge(env().getObjectModule(in), m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graph_ = graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
// memory profile //////////////////////////////////////////////////////////////
|
||||||
|
const VirtualMachine::MemoryProfile & VirtualMachine::getMemoryProfile(void)
|
||||||
|
{
|
||||||
|
if (memoryProfileOutdated_)
|
||||||
|
{
|
||||||
|
makeMemoryProfile();
|
||||||
|
memoryProfileOutdated_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::makeMemoryProfile(void)
|
||||||
|
{
|
||||||
|
bool protect = env().objectsProtected();
|
||||||
|
bool hmsg = HadronsLogMessage.isActive();
|
||||||
|
bool gmsg = GridLogMessage.isActive();
|
||||||
|
bool err = HadronsLogError.isActive();
|
||||||
|
auto program = getModuleGraph().topoSort();
|
||||||
|
|
||||||
|
resetProfile();
|
||||||
|
profile_.module.resize(getNModule());
|
||||||
|
env().protectObjects(false);
|
||||||
|
GridLogMessage.Active(false);
|
||||||
|
HadronsLogMessage.Active(false);
|
||||||
|
HadronsLogError.Active(false);
|
||||||
|
for (auto it = program.rbegin(); it != program.rend(); ++it)
|
||||||
|
{
|
||||||
|
auto a = *it;
|
||||||
|
|
||||||
|
if (profile_.module[a].empty())
|
||||||
|
{
|
||||||
|
LOG(Debug) << "Profiling memory for module '" << module_[a].name
|
||||||
|
<< "' (" << a << ")..." << std::endl;
|
||||||
|
memoryProfile(a);
|
||||||
|
env().freeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env().protectObjects(protect);
|
||||||
|
GridLogMessage.Active(gmsg);
|
||||||
|
HadronsLogMessage.Active(hmsg);
|
||||||
|
HadronsLogError.Active(err);
|
||||||
|
LOG(Debug) << "Memory profile:" << std::endl;
|
||||||
|
LOG(Debug) << "----------------" << std::endl;
|
||||||
|
for (unsigned int a = 0; a < profile_.module.size(); ++a)
|
||||||
|
{
|
||||||
|
LOG(Debug) << getModuleName(a) << " (" << a << ")" << std::endl;
|
||||||
|
for (auto &o: profile_.module[a])
|
||||||
|
{
|
||||||
|
LOG(Debug) << "|__ " << env().getObjectName(o.first) << " ("
|
||||||
|
<< sizeString(o.second) << ")" << std::endl;
|
||||||
|
}
|
||||||
|
LOG(Debug) << std::endl;
|
||||||
|
}
|
||||||
|
LOG(Debug) << "----------------" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::resetProfile(void)
|
||||||
|
{
|
||||||
|
profile_.module.clear();
|
||||||
|
profile_.object.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::resizeProfile(void)
|
||||||
|
{
|
||||||
|
if (env().getMaxAddress() > profile_.object.size())
|
||||||
|
{
|
||||||
|
MemoryPrint empty;
|
||||||
|
|
||||||
|
empty.size = 0;
|
||||||
|
empty.module = -1;
|
||||||
|
profile_.object.resize(env().getMaxAddress(), empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::updateProfile(const unsigned int address)
|
||||||
|
{
|
||||||
|
resizeProfile();
|
||||||
|
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
||||||
|
{
|
||||||
|
if (env().hasCreatedObject(a) and (profile_.object[a].module == -1))
|
||||||
|
{
|
||||||
|
profile_.object[a].size = env().getObjectSize(a);
|
||||||
|
profile_.object[a].storage = env().getObjectStorage(a);
|
||||||
|
profile_.object[a].module = address;
|
||||||
|
profile_.module[address][a] = profile_.object[a].size;
|
||||||
|
if (env().getObjectModule(a) < 0)
|
||||||
|
{
|
||||||
|
env().setObjectModule(a, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::cleanEnvironment(void)
|
||||||
|
{
|
||||||
|
resizeProfile();
|
||||||
|
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
||||||
|
{
|
||||||
|
if (env().hasCreatedObject(a) and (profile_.object[a].module == -1))
|
||||||
|
{
|
||||||
|
env().freeObject(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::memoryProfile(const unsigned int address)
|
||||||
|
{
|
||||||
|
auto m = getModule(address);
|
||||||
|
|
||||||
|
LOG(Debug) << "Setting up module '" << m->getName()
|
||||||
|
<< "' (" << address << ")..." << std::endl;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m->setup();
|
||||||
|
updateProfile(address);
|
||||||
|
}
|
||||||
|
catch (Exceptions::Definition &)
|
||||||
|
{
|
||||||
|
cleanEnvironment();
|
||||||
|
for (auto &in: m->getInput())
|
||||||
|
{
|
||||||
|
memoryProfile(env().getObjectModule(in));
|
||||||
|
}
|
||||||
|
for (auto &ref: m->getReference())
|
||||||
|
{
|
||||||
|
memoryProfile(env().getObjectModule(ref));
|
||||||
|
}
|
||||||
|
m->setup();
|
||||||
|
updateProfile(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::memoryProfile(const std::string name)
|
||||||
|
{
|
||||||
|
memoryProfile(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// garbage collector ///////////////////////////////////////////////////////////
|
||||||
|
VirtualMachine::GarbageSchedule
|
||||||
|
VirtualMachine::makeGarbageSchedule(const Program &p) const
|
||||||
|
{
|
||||||
|
GarbageSchedule freeProg;
|
||||||
|
|
||||||
|
freeProg.resize(p.size());
|
||||||
|
for (unsigned int a = 0; a < env().getMaxAddress(); ++a)
|
||||||
|
{
|
||||||
|
if (env().getObjectStorage(a) == Environment::Storage::temporary)
|
||||||
|
{
|
||||||
|
auto it = std::find(p.begin(), p.end(), env().getObjectModule(a));
|
||||||
|
|
||||||
|
if (it != p.end())
|
||||||
|
{
|
||||||
|
freeProg[std::distance(p.begin(), it)].insert(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (env().getObjectStorage(a) == Environment::Storage::object)
|
||||||
|
{
|
||||||
|
auto pred = [a, this](const unsigned int b)
|
||||||
|
{
|
||||||
|
auto &in = module_[b].input;
|
||||||
|
auto it = std::find(in.begin(), in.end(), a);
|
||||||
|
|
||||||
|
return (it != in.end()) or (b == env().getObjectModule(a));
|
||||||
|
};
|
||||||
|
auto it = std::find_if(p.rbegin(), p.rend(), pred);
|
||||||
|
if (it != p.rend())
|
||||||
|
{
|
||||||
|
freeProg[std::distance(it, p.rend()) - 1].insert(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return freeProg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// high-water memory function //////////////////////////////////////////////////
|
||||||
|
VirtualMachine::Size VirtualMachine::memoryNeeded(const Program &p)
|
||||||
|
{
|
||||||
|
const MemoryProfile &profile = getMemoryProfile();
|
||||||
|
GarbageSchedule freep = makeGarbageSchedule(p);
|
||||||
|
Size current = 0, max = 0;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < p.size(); ++i)
|
||||||
|
{
|
||||||
|
for (auto &o: profile.module[p[i]])
|
||||||
|
{
|
||||||
|
current += o.second;
|
||||||
|
}
|
||||||
|
max = std::max(current, max);
|
||||||
|
for (auto &o: freep[i])
|
||||||
|
{
|
||||||
|
current -= profile.object[o].size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// genetic scheduler ///////////////////////////////////////////////////////////
|
||||||
|
VirtualMachine::Program VirtualMachine::schedule(const GeneticPar &par)
|
||||||
|
{
|
||||||
|
typedef GeneticScheduler<Size, unsigned int> Scheduler;
|
||||||
|
|
||||||
|
auto graph = getModuleGraph();
|
||||||
|
|
||||||
|
//constrained topological sort using a genetic algorithm
|
||||||
|
LOG(Message) << "Scheduling computation..." << std::endl;
|
||||||
|
LOG(Message) << " #module= " << graph.size() << std::endl;
|
||||||
|
LOG(Message) << " population size= " << par.popSize << std::endl;
|
||||||
|
LOG(Message) << " max. generation= " << par.maxGen << std::endl;
|
||||||
|
LOG(Message) << " max. cst. generation= " << par.maxCstGen << std::endl;
|
||||||
|
LOG(Message) << " mutation rate= " << par.mutationRate << std::endl;
|
||||||
|
|
||||||
|
unsigned int k = 0, gen, prevPeak, nCstPeak = 0;
|
||||||
|
std::random_device rd;
|
||||||
|
Scheduler::Parameters gpar;
|
||||||
|
|
||||||
|
gpar.popSize = par.popSize;
|
||||||
|
gpar.mutationRate = par.mutationRate;
|
||||||
|
gpar.seed = rd();
|
||||||
|
CartesianCommunicator::BroadcastWorld(0, &(gpar.seed), sizeof(gpar.seed));
|
||||||
|
Scheduler::ObjFunc memPeak = [this](const Program &p)->Size
|
||||||
|
{
|
||||||
|
return memoryNeeded(p);
|
||||||
|
};
|
||||||
|
Scheduler scheduler(graph, memPeak, gpar);
|
||||||
|
gen = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
LOG(Debug) << "Generation " << gen << ":" << std::endl;
|
||||||
|
scheduler.nextGeneration();
|
||||||
|
if (gen != 0)
|
||||||
|
{
|
||||||
|
if (prevPeak == scheduler.getMinValue())
|
||||||
|
{
|
||||||
|
nCstPeak++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nCstPeak = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prevPeak = scheduler.getMinValue();
|
||||||
|
if (gen % 10 == 0)
|
||||||
|
{
|
||||||
|
LOG(Iterative) << "Generation " << gen << ": "
|
||||||
|
<< sizeString(scheduler.getMinValue()) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
gen++;
|
||||||
|
} while ((gen < par.maxGen) and (nCstPeak < par.maxCstGen));
|
||||||
|
|
||||||
|
return scheduler.getMinSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
// general execution ///////////////////////////////////////////////////////////
|
||||||
|
#define BIG_SEP "==============="
|
||||||
|
#define SEP "---------------"
|
||||||
|
#define MEM_MSG(size) sizeString(size)
|
||||||
|
|
||||||
|
void VirtualMachine::executeProgram(const Program &p) const
|
||||||
|
{
|
||||||
|
Size memPeak = 0, sizeBefore, sizeAfter;
|
||||||
|
GarbageSchedule freeProg;
|
||||||
|
|
||||||
|
// build garbage collection schedule
|
||||||
|
LOG(Debug) << "Building garbage collection schedule..." << std::endl;
|
||||||
|
freeProg = makeGarbageSchedule(p);
|
||||||
|
|
||||||
|
// program execution
|
||||||
|
LOG(Debug) << "Executing program..." << std::endl;
|
||||||
|
for (unsigned int i = 0; i < p.size(); ++i)
|
||||||
|
{
|
||||||
|
// execute module
|
||||||
|
LOG(Message) << SEP << " Measurement step " << i + 1 << "/"
|
||||||
|
<< p.size() << " (module '" << module_[p[i]].name
|
||||||
|
<< "') " << SEP << std::endl;
|
||||||
|
(*module_[p[i]].data)();
|
||||||
|
sizeBefore = env().getTotalSize();
|
||||||
|
// print used memory after execution
|
||||||
|
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
|
||||||
|
<< std::endl;
|
||||||
|
if (sizeBefore > memPeak)
|
||||||
|
{
|
||||||
|
memPeak = sizeBefore;
|
||||||
|
}
|
||||||
|
// garbage collection for step i
|
||||||
|
LOG(Message) << "Garbage collection..." << std::endl;
|
||||||
|
for (auto &j: freeProg[i])
|
||||||
|
{
|
||||||
|
env().freeObject(j);
|
||||||
|
}
|
||||||
|
// print used memory after garbage collection if necessary
|
||||||
|
sizeAfter = env().getTotalSize();
|
||||||
|
if (sizeBefore != sizeAfter)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(Message) << "Nothing to free" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMachine::executeProgram(const std::vector<std::string> &p) const
|
||||||
|
{
|
||||||
|
Program pAddress;
|
||||||
|
|
||||||
|
for (auto &n: p)
|
||||||
|
{
|
||||||
|
pAddress.push_back(getModuleAddress(n));
|
||||||
|
}
|
||||||
|
executeProgram(pAddress);
|
||||||
|
}
|
207
extras/Hadrons/VirtualMachine.hpp
Normal file
207
extras/Hadrons/VirtualMachine.hpp
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/VirtualMachine.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
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
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef Hadrons_VirtualMachine_hpp_
|
||||||
|
#define Hadrons_VirtualMachine_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Graph.hpp>
|
||||||
|
#include <Grid/Hadrons/Environment.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#define DEFINE_VM_ALIAS \
|
||||||
|
inline VirtualMachine & vm(void) const\
|
||||||
|
{\
|
||||||
|
return VirtualMachine::getInstance();\
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Virtual machine for module execution *
|
||||||
|
******************************************************************************/
|
||||||
|
// forward declaration of Module
|
||||||
|
class ModuleBase;
|
||||||
|
|
||||||
|
class VirtualMachine
|
||||||
|
{
|
||||||
|
SINGLETON_DEFCTOR(VirtualMachine);
|
||||||
|
public:
|
||||||
|
typedef SITE_SIZE_TYPE Size;
|
||||||
|
typedef std::unique_ptr<ModuleBase> ModPt;
|
||||||
|
typedef std::vector<std::set<unsigned int>> GarbageSchedule;
|
||||||
|
typedef std::vector<unsigned int> Program;
|
||||||
|
struct MemoryPrint
|
||||||
|
{
|
||||||
|
Size size;
|
||||||
|
Environment::Storage storage;
|
||||||
|
int module;
|
||||||
|
};
|
||||||
|
struct MemoryProfile
|
||||||
|
{
|
||||||
|
std::vector<std::map<unsigned int, Size>> module;
|
||||||
|
std::vector<MemoryPrint> object;
|
||||||
|
};
|
||||||
|
class GeneticPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeneticPar(void):
|
||||||
|
popSize{20}, maxGen{1000}, maxCstGen{100}, mutationRate{.1} {};
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(GeneticPar,
|
||||||
|
unsigned int, popSize,
|
||||||
|
unsigned int, maxGen,
|
||||||
|
unsigned int, maxCstGen,
|
||||||
|
double , mutationRate);
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
struct ModuleInfo
|
||||||
|
{
|
||||||
|
const std::type_info *type{nullptr};
|
||||||
|
std::string name;
|
||||||
|
ModPt data{nullptr};
|
||||||
|
std::vector<unsigned int> input;
|
||||||
|
size_t maxAllocated;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// trajectory counter
|
||||||
|
void setTrajectory(const unsigned int traj);
|
||||||
|
unsigned int getTrajectory(void) const;
|
||||||
|
// module management
|
||||||
|
void pushModule(ModPt &pt);
|
||||||
|
template <typename M>
|
||||||
|
void createModule(const std::string name);
|
||||||
|
template <typename M>
|
||||||
|
void createModule(const std::string name,
|
||||||
|
const typename M::Par &par);
|
||||||
|
void createModule(const std::string name,
|
||||||
|
const std::string type,
|
||||||
|
XmlReader &reader);
|
||||||
|
unsigned int getNModule(void) const;
|
||||||
|
ModuleBase * getModule(const unsigned int address) const;
|
||||||
|
ModuleBase * getModule(const std::string name) const;
|
||||||
|
template <typename M>
|
||||||
|
M * getModule(const unsigned int address) const;
|
||||||
|
template <typename M>
|
||||||
|
M * getModule(const std::string name) const;
|
||||||
|
unsigned int getModuleAddress(const std::string name) const;
|
||||||
|
std::string getModuleName(const unsigned int address) const;
|
||||||
|
std::string getModuleType(const unsigned int address) const;
|
||||||
|
std::string getModuleType(const std::string name) const;
|
||||||
|
std::string getModuleNamespace(const unsigned int address) const;
|
||||||
|
std::string getModuleNamespace(const std::string name) const;
|
||||||
|
bool hasModule(const unsigned int address) const;
|
||||||
|
bool hasModule(const std::string name) const;
|
||||||
|
// print VM content
|
||||||
|
void printContent(void) const;
|
||||||
|
// module graph (could be a const reference if topoSort was const)
|
||||||
|
Graph<unsigned int> getModuleGraph(void);
|
||||||
|
// memory profile
|
||||||
|
const MemoryProfile &getMemoryProfile(void);
|
||||||
|
// garbage collector
|
||||||
|
GarbageSchedule makeGarbageSchedule(const Program &p) const;
|
||||||
|
// high-water memory function
|
||||||
|
Size memoryNeeded(const Program &p);
|
||||||
|
// genetic scheduler
|
||||||
|
Program schedule(const GeneticPar &par);
|
||||||
|
// general execution
|
||||||
|
void executeProgram(const Program &p) const;
|
||||||
|
void executeProgram(const std::vector<std::string> &p) const;
|
||||||
|
private:
|
||||||
|
// environment shortcut
|
||||||
|
DEFINE_ENV_ALIAS;
|
||||||
|
// module graph
|
||||||
|
void makeModuleGraph(void);
|
||||||
|
// memory profile
|
||||||
|
void makeMemoryProfile(void);
|
||||||
|
void resetProfile(void);
|
||||||
|
void resizeProfile(void);
|
||||||
|
void updateProfile(const unsigned int address);
|
||||||
|
void cleanEnvironment(void);
|
||||||
|
void memoryProfile(const std::string name);
|
||||||
|
void memoryProfile(const unsigned int address);
|
||||||
|
private:
|
||||||
|
// general
|
||||||
|
unsigned int traj_;
|
||||||
|
// module and related maps
|
||||||
|
std::vector<ModuleInfo> module_;
|
||||||
|
std::map<std::string, unsigned int> moduleAddress_;
|
||||||
|
std::string currentModule_{""};
|
||||||
|
// module graph
|
||||||
|
bool graphOutdated_{true};
|
||||||
|
Graph<unsigned int> graph_;
|
||||||
|
// memory profile
|
||||||
|
bool memoryProfileOutdated_{true};
|
||||||
|
MemoryProfile profile_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* VirtualMachine template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// module management ///////////////////////////////////////////////////////////
|
||||||
|
template <typename M>
|
||||||
|
void VirtualMachine::createModule(const std::string name)
|
||||||
|
{
|
||||||
|
ModPt pt(new M(name));
|
||||||
|
|
||||||
|
pushModule(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
void VirtualMachine::createModule(const std::string name,
|
||||||
|
const typename M::Par &par)
|
||||||
|
{
|
||||||
|
ModPt pt(new M(name));
|
||||||
|
|
||||||
|
static_cast<M *>(pt.get())->setPar(par);
|
||||||
|
pushModule(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
M * VirtualMachine::getModule(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (auto *pt = dynamic_cast<M *>(getModule(address)))
|
||||||
|
{
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR(Definition, "module '" + module_[address].name
|
||||||
|
+ "' does not have type " + typeid(M).name()
|
||||||
|
+ "(has type: " + getModuleType(address) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
M * VirtualMachine::getModule(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModule<M>(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_VirtualMachine_hpp_
|
@ -1,38 +1,53 @@
|
|||||||
modules_cc =\
|
modules_cc =\
|
||||||
Modules/MContraction/WeakHamiltonianEye.cc \
|
|
||||||
Modules/MContraction/WeakHamiltonianNonEye.cc \
|
|
||||||
Modules/MContraction/WeakNeutral4ptDisc.cc \
|
|
||||||
Modules/MGauge/Load.cc \
|
|
||||||
Modules/MGauge/Random.cc \
|
|
||||||
Modules/MGauge/StochEm.cc \
|
|
||||||
Modules/MGauge/Unit.cc \
|
|
||||||
Modules/MScalar/ChargedProp.cc \
|
Modules/MScalar/ChargedProp.cc \
|
||||||
Modules/MScalar/FreeProp.cc
|
Modules/MScalar/FreeProp.cc \
|
||||||
|
Modules/MContraction/WeakHamiltonianEye.cc \
|
||||||
|
Modules/MContraction/WeakNeutral4ptDisc.cc \
|
||||||
|
Modules/MContraction/WeakHamiltonianNonEye.cc \
|
||||||
|
Modules/MGauge/Unit.cc \
|
||||||
|
Modules/MGauge/StochEm.cc \
|
||||||
|
Modules/MGauge/Random.cc \
|
||||||
|
Modules/MGauge/FundtoHirep.cc \
|
||||||
|
Modules/MScalar/FreeProp.cc \
|
||||||
|
Modules/MScalar/ChargedProp.cc \
|
||||||
|
Modules/MIO/LoadNersc.cc
|
||||||
|
|
||||||
modules_hpp =\
|
modules_hpp =\
|
||||||
Modules/MAction/DWF.hpp \
|
|
||||||
Modules/MAction/Wilson.hpp \
|
|
||||||
Modules/MContraction/Baryon.hpp \
|
Modules/MContraction/Baryon.hpp \
|
||||||
Modules/MContraction/DiscLoop.hpp \
|
|
||||||
Modules/MContraction/Gamma3pt.hpp \
|
|
||||||
Modules/MContraction/Meson.hpp \
|
Modules/MContraction/Meson.hpp \
|
||||||
Modules/MContraction/WeakHamiltonian.hpp \
|
Modules/MContraction/WeakHamiltonian.hpp \
|
||||||
Modules/MContraction/WeakHamiltonianEye.hpp \
|
|
||||||
Modules/MContraction/WeakHamiltonianNonEye.hpp \
|
Modules/MContraction/WeakHamiltonianNonEye.hpp \
|
||||||
|
Modules/MContraction/DiscLoop.hpp \
|
||||||
Modules/MContraction/WeakNeutral4ptDisc.hpp \
|
Modules/MContraction/WeakNeutral4ptDisc.hpp \
|
||||||
|
Modules/MContraction/Gamma3pt.hpp \
|
||||||
|
Modules/MContraction/WardIdentity.hpp \
|
||||||
|
Modules/MContraction/WeakHamiltonianEye.hpp \
|
||||||
Modules/MFermion/GaugeProp.hpp \
|
Modules/MFermion/GaugeProp.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/Z2.hpp \
|
||||||
Modules/MLoop/NoiseLoop.hpp \
|
Modules/MSource/SeqConserved.hpp \
|
||||||
Modules/MScalar/ChargedProp.hpp \
|
Modules/MSink/Smear.hpp \
|
||||||
Modules/MScalar/FreeProp.hpp \
|
|
||||||
Modules/MScalar/Scalar.hpp \
|
|
||||||
Modules/MSink/Point.hpp \
|
Modules/MSink/Point.hpp \
|
||||||
Modules/MSolver/RBPrecCG.hpp \
|
Modules/MSolver/RBPrecCG.hpp \
|
||||||
Modules/MSource/Point.hpp \
|
Modules/MGauge/Unit.hpp \
|
||||||
Modules/MSource/SeqGamma.hpp \
|
Modules/MGauge/Random.hpp \
|
||||||
Modules/MSource/Wall.hpp \
|
Modules/MGauge/StochEm.hpp \
|
||||||
Modules/MSource/Z2.hpp
|
Modules/MGauge/FundtoHirep.hpp \
|
||||||
|
Modules/MUtilities/TestSeqGamma.hpp \
|
||||||
|
Modules/MUtilities/TestSeqConserved.hpp \
|
||||||
|
Modules/MLoop/NoiseLoop.hpp \
|
||||||
|
Modules/MScalar/FreeProp.hpp \
|
||||||
|
Modules/MScalar/Scalar.hpp \
|
||||||
|
Modules/MScalar/ChargedProp.hpp \
|
||||||
|
Modules/MAction/DWF.hpp \
|
||||||
|
Modules/MAction/Wilson.hpp \
|
||||||
|
Modules/MAction/WilsonClover.hpp \
|
||||||
|
Modules/MScalarSUN/Div.hpp \
|
||||||
|
Modules/MScalarSUN/TrMag.hpp \
|
||||||
|
Modules/MScalarSUN/TwoPoint.hpp \
|
||||||
|
Modules/MScalarSUN/TrPhi.hpp \
|
||||||
|
Modules/MIO/LoadNersc.hpp \
|
||||||
|
Modules/MIO/LoadBinary.hpp
|
||||||
|
|
||||||
|
@ -1,28 +1,18 @@
|
|||||||
extra_sources=
|
extra_sources=
|
||||||
extra_headers=
|
extra_headers=
|
||||||
if BUILD_COMMS_MPI
|
|
||||||
extra_sources+=communicator/Communicator_mpi.cc
|
|
||||||
extra_sources+=communicator/Communicator_base.cc
|
|
||||||
endif
|
|
||||||
|
|
||||||
if BUILD_COMMS_MPI3
|
if BUILD_COMMS_MPI3
|
||||||
extra_sources+=communicator/Communicator_mpi3.cc
|
extra_sources+=communicator/Communicator_mpi3.cc
|
||||||
extra_sources+=communicator/Communicator_base.cc
|
extra_sources+=communicator/Communicator_base.cc
|
||||||
endif
|
extra_sources+=communicator/SharedMemoryMPI.cc
|
||||||
|
extra_sources+=communicator/SharedMemory.cc
|
||||||
if BUILD_COMMS_MPIT
|
|
||||||
extra_sources+=communicator/Communicator_mpit.cc
|
|
||||||
extra_sources+=communicator/Communicator_base.cc
|
|
||||||
endif
|
|
||||||
|
|
||||||
if BUILD_COMMS_SHMEM
|
|
||||||
extra_sources+=communicator/Communicator_shmem.cc
|
|
||||||
extra_sources+=communicator/Communicator_base.cc
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_COMMS_NONE
|
if BUILD_COMMS_NONE
|
||||||
extra_sources+=communicator/Communicator_none.cc
|
extra_sources+=communicator/Communicator_none.cc
|
||||||
extra_sources+=communicator/Communicator_base.cc
|
extra_sources+=communicator/Communicator_base.cc
|
||||||
|
extra_sources+=communicator/SharedMemoryNone.cc
|
||||||
|
extra_sources+=communicator/SharedMemory.cc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_HDF5
|
if BUILD_HDF5
|
||||||
|
@ -37,37 +37,25 @@ 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/Deflation.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>
|
||||||
#include <Grid/algorithms/iterative/NormalEquations.h>
|
#include <Grid/algorithms/iterative/NormalEquations.h>
|
||||||
#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>
|
||||||
// Lanczos support
|
#include <Grid/algorithms/iterative/ConjugateGradientReliableUpdate.h>
|
||||||
//#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
|
||||||
|
@ -103,29 +103,32 @@ namespace Grid {
|
|||||||
GridBase *CoarseGrid;
|
GridBase *CoarseGrid;
|
||||||
GridBase *FineGrid;
|
GridBase *FineGrid;
|
||||||
std::vector<Lattice<Fobj> > subspace;
|
std::vector<Lattice<Fobj> > subspace;
|
||||||
|
int checkerboard;
|
||||||
|
|
||||||
Aggregation(GridBase *_CoarseGrid,GridBase *_FineGrid) :
|
Aggregation(GridBase *_CoarseGrid,GridBase *_FineGrid,int _checkerboard) :
|
||||||
CoarseGrid(_CoarseGrid),
|
CoarseGrid(_CoarseGrid),
|
||||||
FineGrid(_FineGrid),
|
FineGrid(_FineGrid),
|
||||||
subspace(nbasis,_FineGrid)
|
subspace(nbasis,_FineGrid),
|
||||||
|
checkerboard(_checkerboard)
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
void Orthogonalise(void){
|
void Orthogonalise(void){
|
||||||
CoarseScalar InnerProd(CoarseGrid);
|
CoarseScalar InnerProd(CoarseGrid);
|
||||||
|
std::cout << GridLogMessage <<" Gramm-Schmidt pass 1"<<std::endl;
|
||||||
blockOrthogonalise(InnerProd,subspace);
|
blockOrthogonalise(InnerProd,subspace);
|
||||||
|
std::cout << GridLogMessage <<" Gramm-Schmidt pass 2"<<std::endl;
|
||||||
|
blockOrthogonalise(InnerProd,subspace);
|
||||||
|
// std::cout << GridLogMessage <<" Gramm-Schmidt checking orthogonality"<<std::endl;
|
||||||
|
// CheckOrthogonal();
|
||||||
}
|
}
|
||||||
void CheckOrthogonal(void){
|
void CheckOrthogonal(void){
|
||||||
CoarseVector iProj(CoarseGrid);
|
CoarseVector iProj(CoarseGrid);
|
||||||
CoarseVector eProj(CoarseGrid);
|
CoarseVector eProj(CoarseGrid);
|
||||||
Lattice<CComplex> pokey(CoarseGrid);
|
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<nbasis;i++){
|
for(int i=0;i<nbasis;i++){
|
||||||
blockProject(iProj,subspace[i],subspace);
|
blockProject(iProj,subspace[i],subspace);
|
||||||
|
|
||||||
eProj=zero;
|
eProj=zero;
|
||||||
for(int ss=0;ss<CoarseGrid->oSites();ss++){
|
parallel_for(int ss=0;ss<CoarseGrid->oSites();ss++){
|
||||||
eProj._odata[ss](i)=CComplex(1.0);
|
eProj._odata[ss](i)=CComplex(1.0);
|
||||||
}
|
}
|
||||||
eProj=eProj - iProj;
|
eProj=eProj - iProj;
|
||||||
@ -137,6 +140,7 @@ namespace Grid {
|
|||||||
blockProject(CoarseVec,FineVec,subspace);
|
blockProject(CoarseVec,FineVec,subspace);
|
||||||
}
|
}
|
||||||
void PromoteFromSubspace(const CoarseVector &CoarseVec,FineField &FineVec){
|
void PromoteFromSubspace(const CoarseVector &CoarseVec,FineField &FineVec){
|
||||||
|
FineVec.checkerboard = subspace[0].checkerboard;
|
||||||
blockPromote(CoarseVec,FineVec,subspace);
|
blockPromote(CoarseVec,FineVec,subspace);
|
||||||
}
|
}
|
||||||
void CreateSubspaceRandom(GridParallelRNG &RNG){
|
void CreateSubspaceRandom(GridParallelRNG &RNG){
|
||||||
@ -147,6 +151,7 @@ namespace Grid {
|
|||||||
Orthogonalise();
|
Orthogonalise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
virtual void CreateSubspaceLanczos(GridParallelRNG &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis)
|
virtual void CreateSubspaceLanczos(GridParallelRNG &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis)
|
||||||
{
|
{
|
||||||
// Run a Lanczos with sloppy convergence
|
// Run a Lanczos with sloppy convergence
|
||||||
@ -195,7 +200,7 @@ namespace Grid {
|
|||||||
std::cout << GridLogMessage <<"subspace["<<b<<"] = "<<norm2(subspace[b])<<std::endl;
|
std::cout << GridLogMessage <<"subspace["<<b<<"] = "<<norm2(subspace[b])<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
virtual void CreateSubspace(GridParallelRNG &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis) {
|
virtual void CreateSubspace(GridParallelRNG &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis) {
|
||||||
|
|
||||||
RealD scale;
|
RealD scale;
|
||||||
|
@ -230,6 +230,7 @@ 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
|
||||||
{
|
{
|
||||||
@ -240,7 +241,8 @@ 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]+=p*L;
|
cbuf[dim]+=((pc+p) % processors[dim])*L;
|
||||||
|
// cbuf[dim]+=p*L;
|
||||||
pokeLocalSite(s,pgbuf,cbuf);
|
pokeLocalSite(s,pgbuf,cbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,7 +280,6 @@ 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);
|
||||||
|
@ -162,15 +162,10 @@ namespace Grid {
|
|||||||
_Mat.M(in,out);
|
_Mat.M(in,out);
|
||||||
}
|
}
|
||||||
void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
||||||
ComplexD dot;
|
|
||||||
|
|
||||||
_Mat.M(in,out);
|
_Mat.M(in,out);
|
||||||
|
|
||||||
dot= innerProduct(in,out);
|
ComplexD dot= innerProduct(in,out); n1=real(dot);
|
||||||
n1=real(dot);
|
n2=norm2(out);
|
||||||
|
|
||||||
dot = innerProduct(out,out);
|
|
||||||
n2=real(dot);
|
|
||||||
}
|
}
|
||||||
void HermOp(const Field &in, Field &out){
|
void HermOp(const Field &in, Field &out){
|
||||||
_Mat.M(in,out);
|
_Mat.M(in,out);
|
||||||
@ -188,14 +183,16 @@ namespace Grid {
|
|||||||
virtual RealD Mpc (const Field &in, Field &out) =0;
|
virtual RealD Mpc (const Field &in, Field &out) =0;
|
||||||
virtual RealD MpcDag (const Field &in, Field &out) =0;
|
virtual RealD MpcDag (const Field &in, Field &out) =0;
|
||||||
virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) {
|
virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) {
|
||||||
Field tmp(in._grid);
|
Field tmp(in._grid);
|
||||||
|
tmp.checkerboard = in.checkerboard;
|
||||||
ni=Mpc(in,tmp);
|
ni=Mpc(in,tmp);
|
||||||
no=MpcDag(tmp,out);
|
no=MpcDag(tmp,out);
|
||||||
}
|
}
|
||||||
void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
||||||
|
out.checkerboard = in.checkerboard;
|
||||||
MpcDagMpc(in,out,n1,n2);
|
MpcDagMpc(in,out,n1,n2);
|
||||||
}
|
}
|
||||||
void HermOp(const Field &in, Field &out){
|
virtual void HermOp(const Field &in, Field &out){
|
||||||
RealD n1,n2;
|
RealD n1,n2;
|
||||||
HermOpAndNorm(in,out,n1,n2);
|
HermOpAndNorm(in,out,n1,n2);
|
||||||
}
|
}
|
||||||
@ -212,7 +209,6 @@ namespace Grid {
|
|||||||
void OpDir (const Field &in, Field &out,int dir,int disp) {
|
void OpDir (const Field &in, Field &out,int dir,int disp) {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
template<class Matrix,class Field>
|
template<class Matrix,class Field>
|
||||||
class SchurDiagMooeeOperator : public SchurOperatorBase<Field> {
|
class SchurDiagMooeeOperator : public SchurOperatorBase<Field> {
|
||||||
@ -221,13 +217,15 @@ namespace Grid {
|
|||||||
public:
|
public:
|
||||||
SchurDiagMooeeOperator (Matrix &Mat): _Mat(Mat){};
|
SchurDiagMooeeOperator (Matrix &Mat): _Mat(Mat){};
|
||||||
virtual RealD Mpc (const Field &in, Field &out) {
|
virtual RealD Mpc (const Field &in, Field &out) {
|
||||||
Field tmp(in._grid);
|
Field tmp(in._grid);
|
||||||
// std::cout <<"grid pointers: in._grid="<< in._grid << " out._grid=" << out._grid << " _Mat.Grid=" << _Mat.Grid() << " _Mat.RedBlackGrid=" << _Mat.RedBlackGrid() << std::endl;
|
tmp.checkerboard = !in.checkerboard;
|
||||||
|
//std::cout <<"grid pointers: in._grid="<< in._grid << " out._grid=" << out._grid << " _Mat.Grid=" << _Mat.Grid() << " _Mat.RedBlackGrid=" << _Mat.RedBlackGrid() << std::endl;
|
||||||
|
|
||||||
_Mat.Meooe(in,tmp);
|
_Mat.Meooe(in,tmp);
|
||||||
_Mat.MooeeInv(tmp,out);
|
_Mat.MooeeInv(tmp,out);
|
||||||
_Mat.Meooe(out,tmp);
|
_Mat.Meooe(out,tmp);
|
||||||
|
|
||||||
|
//std::cout << "cb in " << in.checkerboard << " cb out " << out.checkerboard << std::endl;
|
||||||
_Mat.Mooee(in,out);
|
_Mat.Mooee(in,out);
|
||||||
return axpy_norm(out,-1.0,tmp,out);
|
return axpy_norm(out,-1.0,tmp,out);
|
||||||
}
|
}
|
||||||
@ -270,7 +268,6 @@ namespace Grid {
|
|||||||
return axpy_norm(out,-1.0,tmp,in);
|
return axpy_norm(out,-1.0,tmp,in);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Matrix,class Field>
|
template<class Matrix,class Field>
|
||||||
class SchurDiagTwoOperator : public SchurOperatorBase<Field> {
|
class SchurDiagTwoOperator : public SchurOperatorBase<Field> {
|
||||||
protected:
|
protected:
|
||||||
@ -299,6 +296,59 @@ namespace Grid {
|
|||||||
return axpy_norm(out,-1.0,tmp,in);
|
return axpy_norm(out,-1.0,tmp,in);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Left handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) psi = eta --> ( 1 - Moo^-1 Moe Mee^-1 Meo ) psi = Moo^-1 eta
|
||||||
|
// Right handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) Moo^-1 Moo psi = eta --> ( 1 - Moe Mee^-1 Meo ) Moo^-1 phi=eta ; psi = Moo^-1 phi
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Matrix,class Field> using SchurDiagOneRH = SchurDiagTwoOperator<Matrix,Field> ;
|
||||||
|
template<class Matrix,class Field> using SchurDiagOneLH = SchurDiagOneOperator<Matrix,Field> ;
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Staggered use
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Matrix,class Field>
|
||||||
|
class SchurStaggeredOperator : public SchurOperatorBase<Field> {
|
||||||
|
protected:
|
||||||
|
Matrix &_Mat;
|
||||||
|
public:
|
||||||
|
SchurStaggeredOperator (Matrix &Mat): _Mat(Mat){};
|
||||||
|
virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
||||||
|
GridLogIterative.TimingMode(1);
|
||||||
|
std::cout << GridLogIterative << " HermOpAndNorm "<<std::endl;
|
||||||
|
n2 = Mpc(in,out);
|
||||||
|
std::cout << GridLogIterative << " HermOpAndNorm.Mpc "<<std::endl;
|
||||||
|
ComplexD dot= innerProduct(in,out);
|
||||||
|
std::cout << GridLogIterative << " HermOpAndNorm.innerProduct "<<std::endl;
|
||||||
|
n1 = real(dot);
|
||||||
|
}
|
||||||
|
virtual void HermOp(const Field &in, Field &out){
|
||||||
|
std::cout << GridLogIterative << " HermOp "<<std::endl;
|
||||||
|
Mpc(in,out);
|
||||||
|
}
|
||||||
|
virtual RealD Mpc (const Field &in, Field &out) {
|
||||||
|
Field tmp(in._grid);
|
||||||
|
Field tmp2(in._grid);
|
||||||
|
|
||||||
|
std::cout << GridLogIterative << " HermOp.Mpc "<<std::endl;
|
||||||
|
_Mat.Mooee(in,out);
|
||||||
|
_Mat.Mooee(out,tmp);
|
||||||
|
std::cout << GridLogIterative << " HermOp.MooeeMooee "<<std::endl;
|
||||||
|
|
||||||
|
_Mat.Meooe(in,out);
|
||||||
|
_Mat.Meooe(out,tmp2);
|
||||||
|
std::cout << GridLogIterative << " HermOp.MeooeMeooe "<<std::endl;
|
||||||
|
|
||||||
|
RealD nn=axpy_norm(out,-1.0,tmp2,tmp);
|
||||||
|
std::cout << GridLogIterative << " HermOp.axpy_norm "<<std::endl;
|
||||||
|
return nn;
|
||||||
|
}
|
||||||
|
virtual RealD MpcDag (const Field &in, Field &out){
|
||||||
|
return Mpc(in,out);
|
||||||
|
}
|
||||||
|
virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) {
|
||||||
|
assert(0);// Never need with staggered
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<class Matrix,class Field> using SchurStagOperator = SchurStaggeredOperator<Matrix,Field>;
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
@ -314,6 +364,14 @@ namespace Grid {
|
|||||||
virtual void operator() (const Field &in, Field &out) = 0;
|
virtual void operator() (const Field &in, Field &out) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Field> class IdentityLinearFunction : public LinearFunction<Field> {
|
||||||
|
public:
|
||||||
|
void operator() (const Field &in, Field &out){
|
||||||
|
out = in;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
// Base classes for Multishift solvers for operators
|
// Base classes for Multishift solvers for operators
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
@ -336,6 +394,64 @@ namespace Grid {
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Hermitian operator Linear function and operator function
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Field>
|
||||||
|
class HermOpOperatorFunction : public OperatorFunction<Field> {
|
||||||
|
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
||||||
|
Linop.HermOp(in,out);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Field>
|
||||||
|
class PlainHermOp : public LinearFunction<Field> {
|
||||||
|
public:
|
||||||
|
LinearOperatorBase<Field> &_Linop;
|
||||||
|
|
||||||
|
PlainHermOp(LinearOperatorBase<Field>& linop) : _Linop(linop)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(const Field& in, Field& out) {
|
||||||
|
_Linop.HermOp(in,out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Field>
|
||||||
|
class FunctionHermOp : public LinearFunction<Field> {
|
||||||
|
public:
|
||||||
|
OperatorFunction<Field> & _poly;
|
||||||
|
LinearOperatorBase<Field> &_Linop;
|
||||||
|
|
||||||
|
FunctionHermOp(OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop)
|
||||||
|
: _poly(poly), _Linop(linop) {};
|
||||||
|
|
||||||
|
void operator()(const Field& in, Field& out) {
|
||||||
|
_poly(_Linop,in,out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Field>
|
||||||
|
class Polynomial : public OperatorFunction<Field> {
|
||||||
|
private:
|
||||||
|
std::vector<RealD> Coeffs;
|
||||||
|
public:
|
||||||
|
Polynomial(std::vector<RealD> &_Coeffs) : Coeffs(_Coeffs) { };
|
||||||
|
|
||||||
|
// Implement the required interface
|
||||||
|
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
||||||
|
|
||||||
|
Field AtoN(in._grid);
|
||||||
|
Field Mtmp(in._grid);
|
||||||
|
AtoN = in;
|
||||||
|
out = AtoN*Coeffs[0];
|
||||||
|
for(int n=1;n<Coeffs.size();n++){
|
||||||
|
Mtmp = AtoN;
|
||||||
|
Linop.HermOp(Mtmp,AtoN);
|
||||||
|
out=out+AtoN*Coeffs[n];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||||
|
Author: Christoph Lehner <clehner@bnl.gov>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -33,41 +34,12 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
struct ChebyParams : Serializable {
|
||||||
// Simple general polynomial with user supplied coefficients
|
GRID_SERIALIZABLE_CLASS_MEMBERS(ChebyParams,
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
RealD, alpha,
|
||||||
template<class Field>
|
RealD, beta,
|
||||||
class HermOpOperatorFunction : public OperatorFunction<Field> {
|
int, Npoly);
|
||||||
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
};
|
||||||
Linop.HermOp(in,out);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Field>
|
|
||||||
class Polynomial : public OperatorFunction<Field> {
|
|
||||||
private:
|
|
||||||
std::vector<RealD> Coeffs;
|
|
||||||
public:
|
|
||||||
Polynomial(std::vector<RealD> &_Coeffs) : Coeffs(_Coeffs) { };
|
|
||||||
|
|
||||||
// Implement the required interface
|
|
||||||
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
|
||||||
|
|
||||||
Field AtoN(in._grid);
|
|
||||||
Field Mtmp(in._grid);
|
|
||||||
AtoN = in;
|
|
||||||
out = AtoN*Coeffs[0];
|
|
||||||
// std::cout <<"Poly in " <<norm2(in)<<" size "<< Coeffs.size()<<std::endl;
|
|
||||||
// std::cout <<"Coeffs[0]= "<<Coeffs[0]<< " 0 " <<norm2(out)<<std::endl;
|
|
||||||
for(int n=1;n<Coeffs.size();n++){
|
|
||||||
Mtmp = AtoN;
|
|
||||||
Linop.HermOp(Mtmp,AtoN);
|
|
||||||
out=out+AtoN*Coeffs[n];
|
|
||||||
// std::cout <<"Coeffs "<<n<<"= "<< Coeffs[n]<< " 0 " <<std::endl;
|
|
||||||
// std::cout << n<<" " <<norm2(out)<<std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Generic Chebyshev approximations
|
// Generic Chebyshev approximations
|
||||||
@ -82,8 +54,10 @@ namespace Grid {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void csv(std::ostream &out){
|
void csv(std::ostream &out){
|
||||||
RealD diff = hi-lo;
|
RealD diff = hi-lo;
|
||||||
for (RealD x=lo-0.2*diff; x<hi+0.2*diff; x+=(hi-lo)/1000) {
|
RealD delta = (hi-lo)*1.0e-9;
|
||||||
|
for (RealD x=lo; x<hi; x+=delta) {
|
||||||
|
delta*=1.1;
|
||||||
RealD f = approx(x);
|
RealD f = approx(x);
|
||||||
out<< x<<" "<<f<<std::endl;
|
out<< x<<" "<<f<<std::endl;
|
||||||
}
|
}
|
||||||
@ -99,6 +73,7 @@ namespace Grid {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Chebyshev(){};
|
Chebyshev(){};
|
||||||
|
Chebyshev(ChebyParams p){ Init(p.alpha,p.beta,p.Npoly);};
|
||||||
Chebyshev(RealD _lo,RealD _hi,int _order, RealD (* func)(RealD) ) {Init(_lo,_hi,_order,func);};
|
Chebyshev(RealD _lo,RealD _hi,int _order, RealD (* func)(RealD) ) {Init(_lo,_hi,_order,func);};
|
||||||
Chebyshev(RealD _lo,RealD _hi,int _order) {Init(_lo,_hi,_order);};
|
Chebyshev(RealD _lo,RealD _hi,int _order) {Init(_lo,_hi,_order);};
|
||||||
|
|
||||||
@ -193,6 +168,47 @@ namespace Grid {
|
|||||||
return sum;
|
return sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
RealD approxD(RealD x)
|
||||||
|
{
|
||||||
|
RealD Un;
|
||||||
|
RealD Unm;
|
||||||
|
RealD Unp;
|
||||||
|
|
||||||
|
RealD y=( x-0.5*(hi+lo))/(0.5*(hi-lo));
|
||||||
|
|
||||||
|
RealD U0=1;
|
||||||
|
RealD U1=2*y;
|
||||||
|
|
||||||
|
RealD sum;
|
||||||
|
sum = Coeffs[1]*U0;
|
||||||
|
sum+= Coeffs[2]*U1*2.0;
|
||||||
|
|
||||||
|
Un =U1;
|
||||||
|
Unm=U0;
|
||||||
|
for(int i=2;i<order-1;i++){
|
||||||
|
Unp=2*y*Un-Unm;
|
||||||
|
Unm=Un;
|
||||||
|
Un =Unp;
|
||||||
|
sum+= Un*Coeffs[i+1]*(i+1.0);
|
||||||
|
}
|
||||||
|
return sum/(0.5*(hi-lo));
|
||||||
|
};
|
||||||
|
|
||||||
|
RealD approxInv(RealD z, RealD x0, int maxiter, RealD resid) {
|
||||||
|
RealD x = x0;
|
||||||
|
RealD eps;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i=0;i<maxiter;i++) {
|
||||||
|
eps = approx(x) - z;
|
||||||
|
if (fabs(eps / z) < resid)
|
||||||
|
return x;
|
||||||
|
x = x - eps / approxD(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::numeric_limits<double>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
// Implement the required interface
|
// Implement the required interface
|
||||||
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
||||||
|
|
||||||
|
152
lib/algorithms/approx/Forecast.h
Normal file
152
lib/algorithms/approx/Forecast.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
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,15 +87,22 @@ 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
|
||||||
// Cholesky from Eigen
|
m_rr = 0.5*(m_rr+m_rr.adjoint());
|
||||||
// There exists a ldlt that is documented as more stable
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
Eigen::MatrixXcd L = m_rr.llt().matrixL();
|
|
||||||
|
|
||||||
|
#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();
|
||||||
|
// 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}
|
||||||
//
|
//
|
||||||
@ -103,7 +110,6 @@ 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,
|
void operator()(LinearOperatorBase<Field> &Linop, const Field &src, Field &psi) {
|
||||||
Field &psi) {
|
|
||||||
psi.checkerboard = src.checkerboard;
|
psi.checkerboard = src.checkerboard;
|
||||||
conformable(psi, src);
|
conformable(psi, src);
|
||||||
|
|
||||||
@ -78,12 +78,12 @@ class ConjugateGradient : public OperatorFunction<Field> {
|
|||||||
cp = a;
|
cp = a;
|
||||||
ssq = norm2(src);
|
ssq = norm2(src);
|
||||||
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: guess " << guess << std::endl;
|
std::cout << GridLogIterative << std::setprecision(8) << "ConjugateGradient: guess " << guess << std::endl;
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: src " << ssq << std::endl;
|
std::cout << GridLogIterative << std::setprecision(8) << "ConjugateGradient: src " << ssq << std::endl;
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: mp " << d << std::endl;
|
std::cout << GridLogIterative << std::setprecision(8) << "ConjugateGradient: mp " << d << std::endl;
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: mmp " << b << std::endl;
|
std::cout << GridLogIterative << std::setprecision(8) << "ConjugateGradient: mmp " << b << std::endl;
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: cp,r " << cp << std::endl;
|
std::cout << GridLogIterative << std::setprecision(8) << "ConjugateGradient: cp,r " << cp << std::endl;
|
||||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: p " << a << std::endl;
|
std::cout << GridLogIterative << std::setprecision(8) << "ConjugateGradient: p " << a << std::endl;
|
||||||
|
|
||||||
RealD rsq = Tolerance * Tolerance * ssq;
|
RealD rsq = Tolerance * Tolerance * ssq;
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ class ConjugateGradient : public OperatorFunction<Field> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << GridLogIterative << std::setprecision(4)
|
std::cout << GridLogIterative << std::setprecision(8)
|
||||||
<< "ConjugateGradient: k=0 residual " << cp << " target " << rsq << std::endl;
|
<< "ConjugateGradient: k=0 residual " << cp << " target " << rsq << std::endl;
|
||||||
|
|
||||||
GridStopWatch LinalgTimer;
|
GridStopWatch LinalgTimer;
|
||||||
|
256
lib/algorithms/iterative/ConjugateGradientReliableUpdate.h
Normal file
256
lib/algorithms/iterative/ConjugateGradientReliableUpdate.h
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
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
|
101
lib/algorithms/iterative/Deflation.h
Normal file
101
lib/algorithms/iterative/Deflation.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./lib/algorithms/iterative/ImplicitlyRestartedLanczos.h
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef GRID_DEFLATION_H
|
||||||
|
#define GRID_DEFLATION_H
|
||||||
|
|
||||||
|
namespace Grid {
|
||||||
|
|
||||||
|
struct ZeroGuesser {
|
||||||
|
public:
|
||||||
|
template<class Field>
|
||||||
|
void operator()(const Field &src,Field &guess) { guess = Zero(); };
|
||||||
|
};
|
||||||
|
struct SourceGuesser {
|
||||||
|
public:
|
||||||
|
template<class Field>
|
||||||
|
void operator()(const Field &src,Field &guess) { guess = src; };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// Fine grid deflation
|
||||||
|
////////////////////////////////
|
||||||
|
template<class Field>
|
||||||
|
struct DeflatedGuesser {
|
||||||
|
private:
|
||||||
|
const std::vector<Field> &evec;
|
||||||
|
const std::vector<RealD> &eval;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DeflatedGuesser(const std::vector<Field> & _evec,const std::vector<RealD> & _eval) : evec(_evec), eval(_eval) {};
|
||||||
|
|
||||||
|
void operator()(const Field &src,Field &guess) {
|
||||||
|
guess = zero;
|
||||||
|
assert(evec.size()==eval.size());
|
||||||
|
auto N = evec.size();
|
||||||
|
for (int i=0;i<N;i++) {
|
||||||
|
const Field& tmp = evec[i];
|
||||||
|
axpy(guess,TensorRemove(innerProduct(tmp,src)) / eval[i],tmp,guess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class FineField, class CoarseField>
|
||||||
|
class LocalCoherenceDeflatedGuesser {
|
||||||
|
private:
|
||||||
|
const std::vector<FineField> &subspace;
|
||||||
|
const std::vector<CoarseField> &evec_coarse;
|
||||||
|
const std::vector<RealD> &eval_coarse;
|
||||||
|
public:
|
||||||
|
|
||||||
|
LocalCoherenceDeflatedGuesser(const std::vector<FineField> &_subspace,
|
||||||
|
const std::vector<CoarseField> &_evec_coarse,
|
||||||
|
const std::vector<RealD> &_eval_coarse)
|
||||||
|
: subspace(_subspace),
|
||||||
|
evec_coarse(_evec_coarse),
|
||||||
|
eval_coarse(_eval_coarse)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(const FineField &src,FineField &guess) {
|
||||||
|
int N = (int)evec_coarse.size();
|
||||||
|
CoarseField src_coarse(evec_coarse[0]._grid);
|
||||||
|
CoarseField guess_coarse(evec_coarse[0]._grid); guess_coarse = zero;
|
||||||
|
blockProject(src_coarse,src,subspace);
|
||||||
|
for (int i=0;i<N;i++) {
|
||||||
|
const CoarseField & tmp = evec_coarse[i];
|
||||||
|
axpy(guess_coarse,TensorRemove(innerProduct(tmp,src_coarse)) / eval_coarse[i],tmp,guess_coarse);
|
||||||
|
}
|
||||||
|
blockPromote(guess_coarse,guess,subspace);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
@ -7,8 +7,9 @@
|
|||||||
Copyright (C) 2015
|
Copyright (C) 2015
|
||||||
|
|
||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
Author: Chulwoo Jung
|
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||||
Author: Guido Cossu
|
Author: Chulwoo Jung <chulwoo@bnl.gov>
|
||||||
|
Author: Christoph Lehner <clehner@bnl.gov>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -27,108 +28,264 @@ Author: Guido Cossu
|
|||||||
See the full license in the file "LICENSE" in the top level distribution directory
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
#ifndef GRID_IRL_H
|
#ifndef GRID_BIRL_H
|
||||||
#define GRID_IRL_H
|
#define GRID_BIRL_H
|
||||||
|
|
||||||
#include <string.h> //memset
|
#include <string.h> //memset
|
||||||
|
//#include <zlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
enum IRLdiagonalisation {
|
////////////////////////////////////////////////////////
|
||||||
IRLdiagonaliseWithDSTEGR,
|
// Move following 100 LOC to lattice/Lattice_basis.h
|
||||||
IRLdiagonaliseWithQR,
|
////////////////////////////////////////////////////////
|
||||||
IRLdiagonaliseWithEigen
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Helper class for sorting the evalues AND evectors by Field
|
|
||||||
// Use pointer swizzle on vectors
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
template<class Field>
|
template<class Field>
|
||||||
class SortEigen {
|
void basisOrthogonalize(std::vector<Field> &basis,Field &w,int k)
|
||||||
private:
|
{
|
||||||
static bool less_lmd(RealD left,RealD right){
|
for(int j=0; j<k; ++j){
|
||||||
return left > right;
|
auto ip = innerProduct(basis[j],w);
|
||||||
}
|
w = w - ip*basis[j];
|
||||||
static bool less_pair(std::pair<RealD,Field const*>& left,
|
|
||||||
std::pair<RealD,Field const*>& right){
|
|
||||||
return left.first > (right.first);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
template<class Field>
|
||||||
void push(std::vector<RealD>& lmd,std::vector<Field>& evec,int N) {
|
void basisRotate(std::vector<Field> &basis,Eigen::MatrixXd& Qt,int j0, int j1, int k0,int k1,int Nm)
|
||||||
|
{
|
||||||
|
typedef typename Field::vector_object vobj;
|
||||||
|
GridBase* grid = basis[0]._grid;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
parallel_region
|
||||||
// PAB: FIXME: VERY VERY VERY wasteful: takes a copy of the entire vector set.
|
{
|
||||||
// : The vector reorder should be done by pointer swizzle somehow
|
std::vector < vobj > B(Nm); // Thread private
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
std::vector<Field> cpy(lmd.size(),evec[0]._grid);
|
|
||||||
for(int i=0;i<lmd.size();i++) cpy[i] = evec[i];
|
|
||||||
|
|
||||||
std::vector<std::pair<RealD, Field const*> > emod(lmd.size());
|
parallel_for_internal(int ss=0;ss < grid->oSites();ss++){
|
||||||
|
for(int j=j0; j<j1; ++j) B[j]=0.;
|
||||||
|
|
||||||
for(int i=0;i<lmd.size();++i) emod[i] = std::pair<RealD,Field const*>(lmd[i],&cpy[i]);
|
for(int j=j0; j<j1; ++j){
|
||||||
|
for(int k=k0; k<k1; ++k){
|
||||||
partial_sort(emod.begin(),emod.begin()+N,emod.end(),less_pair);
|
B[j] +=Qt(j,k) * basis[k]._odata[ss];
|
||||||
|
}
|
||||||
typename std::vector<std::pair<RealD, Field const*> >::iterator it = emod.begin();
|
}
|
||||||
for(int i=0;i<N;++i){
|
for(int j=j0; j<j1; ++j){
|
||||||
lmd[i]=it->first;
|
basis[j]._odata[ss] = B[j];
|
||||||
evec[i]=*(it->second);
|
}
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void push(std::vector<RealD>& lmd,int N) {
|
}
|
||||||
std::partial_sort(lmd.begin(),lmd.begin()+N,lmd.end(),less_lmd);
|
|
||||||
|
// Extract a single rotated vector
|
||||||
|
template<class Field>
|
||||||
|
void basisRotateJ(Field &result,std::vector<Field> &basis,Eigen::MatrixXd& Qt,int j, int k0,int k1,int Nm)
|
||||||
|
{
|
||||||
|
typedef typename Field::vector_object vobj;
|
||||||
|
GridBase* grid = basis[0]._grid;
|
||||||
|
|
||||||
|
result.checkerboard = basis[0].checkerboard;
|
||||||
|
parallel_for(int ss=0;ss < grid->oSites();ss++){
|
||||||
|
vobj B = zero;
|
||||||
|
for(int k=k0; k<k1; ++k){
|
||||||
|
B +=Qt(j,k) * basis[k]._odata[ss];
|
||||||
|
}
|
||||||
|
result._odata[ss] = B;
|
||||||
}
|
}
|
||||||
bool saturated(RealD lmd, RealD thrs) {
|
}
|
||||||
return fabs(lmd) > fabs(thrs);
|
|
||||||
|
template<class Field>
|
||||||
|
void basisReorderInPlace(std::vector<Field> &_v,std::vector<RealD>& sort_vals, std::vector<int>& idx)
|
||||||
|
{
|
||||||
|
int vlen = idx.size();
|
||||||
|
|
||||||
|
assert(vlen>=1);
|
||||||
|
assert(vlen<=sort_vals.size());
|
||||||
|
assert(vlen<=_v.size());
|
||||||
|
|
||||||
|
for (size_t i=0;i<vlen;i++) {
|
||||||
|
|
||||||
|
if (idx[i] != i) {
|
||||||
|
|
||||||
|
//////////////////////////////////////
|
||||||
|
// idx[i] is a table of desired sources giving a permutation.
|
||||||
|
// Swap v[i] with v[idx[i]].
|
||||||
|
// Find j>i for which _vnew[j] = _vold[i],
|
||||||
|
// track the move idx[j] => idx[i]
|
||||||
|
// track the move idx[i] => i
|
||||||
|
//////////////////////////////////////
|
||||||
|
size_t j;
|
||||||
|
for (j=i;j<idx.size();j++)
|
||||||
|
if (idx[j]==i)
|
||||||
|
break;
|
||||||
|
|
||||||
|
assert(idx[i] > i); assert(j!=idx.size()); assert(idx[j]==i);
|
||||||
|
|
||||||
|
std::swap(_v[i]._odata,_v[idx[i]]._odata); // should use vector move constructor, no data copy
|
||||||
|
std::swap(sort_vals[i],sort_vals[idx[i]]);
|
||||||
|
|
||||||
|
idx[j] = idx[i];
|
||||||
|
idx[i] = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
inline std::vector<int> basisSortGetIndex(std::vector<RealD>& sort_vals)
|
||||||
|
{
|
||||||
|
std::vector<int> idx(sort_vals.size());
|
||||||
|
std::iota(idx.begin(), idx.end(), 0);
|
||||||
|
|
||||||
|
// sort indexes based on comparing values in v
|
||||||
|
std::sort(idx.begin(), idx.end(), [&sort_vals](int i1, int i2) {
|
||||||
|
return ::fabs(sort_vals[i1]) < ::fabs(sort_vals[i2]);
|
||||||
|
});
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Field>
|
||||||
|
void basisSortInPlace(std::vector<Field> & _v,std::vector<RealD>& sort_vals, bool reverse)
|
||||||
|
{
|
||||||
|
std::vector<int> idx = basisSortGetIndex(sort_vals);
|
||||||
|
if (reverse)
|
||||||
|
std::reverse(idx.begin(), idx.end());
|
||||||
|
|
||||||
|
basisReorderInPlace(_v,sort_vals,idx);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
// Implicitly restarted lanczos
|
// Implicitly restarted lanczos
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
template<class Field> class ImplicitlyRestartedLanczosTester
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int TestConvergence(int j,RealD resid,Field &evec, RealD &eval,RealD evalMaxApprox)=0;
|
||||||
|
virtual int ReconstructEval(int j,RealD resid,Field &evec, RealD &eval,RealD evalMaxApprox)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum IRLdiagonalisation {
|
||||||
|
IRLdiagonaliseWithDSTEGR,
|
||||||
|
IRLdiagonaliseWithQR,
|
||||||
|
IRLdiagonaliseWithEigen
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Field> class ImplicitlyRestartedLanczosHermOpTester : public ImplicitlyRestartedLanczosTester<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
LinearFunction<Field> &_HermOp;
|
||||||
|
ImplicitlyRestartedLanczosHermOpTester(LinearFunction<Field> &HermOp) : _HermOp(HermOp) { };
|
||||||
|
int ReconstructEval(int j,RealD resid,Field &B, RealD &eval,RealD evalMaxApprox)
|
||||||
|
{
|
||||||
|
return TestConvergence(j,resid,B,eval,evalMaxApprox);
|
||||||
|
}
|
||||||
|
int TestConvergence(int j,RealD eresid,Field &B, RealD &eval,RealD evalMaxApprox)
|
||||||
|
{
|
||||||
|
Field v(B);
|
||||||
|
RealD eval_poly = eval;
|
||||||
|
// Apply operator
|
||||||
|
_HermOp(B,v);
|
||||||
|
|
||||||
|
RealD vnum = real(innerProduct(B,v)); // HermOp.
|
||||||
|
RealD vden = norm2(B);
|
||||||
|
RealD vv0 = norm2(v);
|
||||||
|
eval = vnum/vden;
|
||||||
|
v -= eval*B;
|
||||||
|
|
||||||
|
RealD vv = norm2(v) / ::pow(evalMaxApprox,2.0);
|
||||||
|
|
||||||
|
std::cout.precision(13);
|
||||||
|
std::cout<<GridLogIRL << "[" << std::setw(3)<<j<<"] "
|
||||||
|
<<"eval = "<<std::setw(25)<< eval << " (" << eval_poly << ")"
|
||||||
|
<<" |H B[i] - eval[i]B[i]|^2 / evalMaxApprox^2 " << std::setw(25) << vv
|
||||||
|
<<std::endl;
|
||||||
|
|
||||||
|
int conv=0;
|
||||||
|
if( (vv<eresid*eresid) ) conv = 1;
|
||||||
|
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class Field>
|
template<class Field>
|
||||||
class ImplicitlyRestartedLanczos {
|
class ImplicitlyRestartedLanczos {
|
||||||
|
private:
|
||||||
private:
|
const RealD small = 1.0e-8;
|
||||||
|
int MaxIter;
|
||||||
int MaxIter; // Max iterations
|
int MinRestart; // Minimum number of restarts; only check for convergence after
|
||||||
int Nstop; // Number of evecs checked for convergence
|
int Nstop; // Number of evecs checked for convergence
|
||||||
int Nk; // Number of converged sought
|
int Nk; // Number of converged sought
|
||||||
int Nm; // Nm -- total number of vectors
|
// int Np; // Np -- Number of spare vecs in krylov space // == Nm - Nk
|
||||||
RealD eresid;
|
int Nm; // Nm -- total number of vectors
|
||||||
IRLdiagonalisation diagonalisation;
|
IRLdiagonalisation diagonalisation;
|
||||||
////////////////////////////////////
|
int orth_period;
|
||||||
// Embedded objects
|
|
||||||
////////////////////////////////////
|
|
||||||
SortEigen<Field> _sort;
|
|
||||||
LinearOperatorBase<Field> &_Linop;
|
|
||||||
OperatorFunction<Field> &_poly;
|
|
||||||
|
|
||||||
|
RealD OrthoTime;
|
||||||
|
RealD eresid, betastp;
|
||||||
|
////////////////////////////////
|
||||||
|
// Embedded objects
|
||||||
|
////////////////////////////////
|
||||||
|
LinearFunction<Field> &_PolyOp;
|
||||||
|
LinearFunction<Field> &_HermOp;
|
||||||
|
ImplicitlyRestartedLanczosTester<Field> &_Tester;
|
||||||
|
// Default tester provided (we need a ref to something in default case)
|
||||||
|
ImplicitlyRestartedLanczosHermOpTester<Field> SimpleTester;
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ImplicitlyRestartedLanczos(LinearOperatorBase<Field> &Linop, // op
|
|
||||||
OperatorFunction<Field> & poly, // polynomial
|
//////////////////////////////////////////////////////////////////
|
||||||
int _Nstop, // really sought vecs
|
// PAB:
|
||||||
int _Nk, // sought vecs
|
//////////////////////////////////////////////////////////////////
|
||||||
int _Nm, // total vecs
|
// Too many options & knobs.
|
||||||
RealD _eresid, // resid in lmd deficit
|
// Eliminate:
|
||||||
int _MaxIter, // Max iterations
|
// orth_period
|
||||||
IRLdiagonalisation _diagonalisation= IRLdiagonaliseWithEigen ) :
|
// betastp
|
||||||
_Linop(Linop), _poly(poly),
|
// MinRestart
|
||||||
Nstop(_Nstop), Nk(_Nk), Nm(_Nm),
|
//
|
||||||
eresid(_eresid), MaxIter(_MaxIter),
|
// Do we really need orth_period
|
||||||
diagonalisation(_diagonalisation)
|
// What is the theoretical basis & guarantees of betastp ?
|
||||||
{ };
|
// Nstop=Nk viable?
|
||||||
|
// MinRestart avoidable with new convergence test?
|
||||||
|
// Could cut to PolyOp, HermOp, Tester, Nk, Nm, resid, maxiter (+diagonalisation)
|
||||||
|
// HermOp could be eliminated if we dropped the Power method for max eval.
|
||||||
|
// -- also: The eval, eval2, eval2_copy stuff is still unnecessarily unclear
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
ImplicitlyRestartedLanczos(LinearFunction<Field> & PolyOp,
|
||||||
|
LinearFunction<Field> & HermOp,
|
||||||
|
ImplicitlyRestartedLanczosTester<Field> & Tester,
|
||||||
|
int _Nstop, // sought vecs
|
||||||
|
int _Nk, // sought vecs
|
||||||
|
int _Nm, // spare vecs
|
||||||
|
RealD _eresid, // resid in lmdue deficit
|
||||||
|
int _MaxIter, // Max iterations
|
||||||
|
RealD _betastp=0.0, // if beta(k) < betastp: converged
|
||||||
|
int _MinRestart=1, int _orth_period = 1,
|
||||||
|
IRLdiagonalisation _diagonalisation= IRLdiagonaliseWithEigen) :
|
||||||
|
SimpleTester(HermOp), _PolyOp(PolyOp), _HermOp(HermOp), _Tester(Tester),
|
||||||
|
Nstop(_Nstop) , Nk(_Nk), Nm(_Nm),
|
||||||
|
eresid(_eresid), betastp(_betastp),
|
||||||
|
MaxIter(_MaxIter) , MinRestart(_MinRestart),
|
||||||
|
orth_period(_orth_period), diagonalisation(_diagonalisation) { };
|
||||||
|
|
||||||
|
ImplicitlyRestartedLanczos(LinearFunction<Field> & PolyOp,
|
||||||
|
LinearFunction<Field> & HermOp,
|
||||||
|
int _Nstop, // sought vecs
|
||||||
|
int _Nk, // sought vecs
|
||||||
|
int _Nm, // spare vecs
|
||||||
|
RealD _eresid, // resid in lmdue deficit
|
||||||
|
int _MaxIter, // Max iterations
|
||||||
|
RealD _betastp=0.0, // if beta(k) < betastp: converged
|
||||||
|
int _MinRestart=1, int _orth_period = 1,
|
||||||
|
IRLdiagonalisation _diagonalisation= IRLdiagonaliseWithEigen) :
|
||||||
|
SimpleTester(HermOp), _PolyOp(PolyOp), _HermOp(HermOp), _Tester(SimpleTester),
|
||||||
|
Nstop(_Nstop) , Nk(_Nk), Nm(_Nm),
|
||||||
|
eresid(_eresid), betastp(_betastp),
|
||||||
|
MaxIter(_MaxIter) , MinRestart(_MinRestart),
|
||||||
|
orth_period(_orth_period), diagonalisation(_diagonalisation) { };
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// Helpers
|
// Helpers
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
static RealD normalise(Field& v)
|
template<typename T> static RealD normalise(T& v)
|
||||||
{
|
{
|
||||||
RealD nn = norm2(v);
|
RealD nn = norm2(v);
|
||||||
nn = sqrt(nn);
|
nn = sqrt(nn);
|
||||||
@ -136,16 +293,12 @@ public:
|
|||||||
return nn;
|
return nn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void orthogonalize(Field& w, std::vector<Field>& evec, int k)
|
void orthogonalize(Field& w, std::vector<Field>& evec,int k)
|
||||||
{
|
{
|
||||||
typedef typename Field::scalar_type MyComplex;
|
OrthoTime-=usecond()/1e6;
|
||||||
MyComplex ip;
|
basisOrthogonalize(evec,w,k);
|
||||||
|
|
||||||
for(int j=0; j<k; ++j){
|
|
||||||
ip = innerProduct(evec[j],w);
|
|
||||||
w = w - ip * evec[j];
|
|
||||||
}
|
|
||||||
normalise(w);
|
normalise(w);
|
||||||
|
OrthoTime+=usecond()/1e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rudy Arthur's thesis pp.137
|
/* Rudy Arthur's thesis pp.137
|
||||||
@ -165,184 +318,238 @@ repeat
|
|||||||
→AVK =VKHK +fKe†K † Extend to an M = K + P step factorization AVM = VMHM + fMeM
|
→AVK =VKHK +fKe†K † Extend to an M = K + P step factorization AVM = VMHM + fMeM
|
||||||
until convergence
|
until convergence
|
||||||
*/
|
*/
|
||||||
void calc(std::vector<RealD>& eval, std::vector<Field>& evec, const Field& src, int& Nconv)
|
void calc(std::vector<RealD>& eval, std::vector<Field>& evec, const Field& src, int& Nconv, bool reverse=false)
|
||||||
{
|
{
|
||||||
|
GridBase *grid = src._grid;
|
||||||
|
assert(grid == evec[0]._grid);
|
||||||
|
|
||||||
GridBase *grid = evec[0]._grid;
|
GridLogIRL.TimingMode(1);
|
||||||
assert(grid == src._grid);
|
std::cout << GridLogIRL <<"**************************************************************************"<< std::endl;
|
||||||
|
std::cout << GridLogIRL <<" ImplicitlyRestartedLanczos::calc() starting iteration 0 / "<< MaxIter<< std::endl;
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
std::cout << GridLogIRL <<"**************************************************************************"<< std::endl;
|
||||||
std::cout << GridLogMessage <<" ImplicitlyRestartedLanczos::calc() starting iteration 0 / "<< MaxIter<< std::endl;
|
std::cout << GridLogIRL <<" -- seek Nk = " << Nk <<" vectors"<< std::endl;
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
std::cout << GridLogIRL <<" -- accept Nstop = " << Nstop <<" vectors"<< std::endl;
|
||||||
std::cout << GridLogMessage <<" -- seek Nk = " << Nk <<" vectors"<< std::endl;
|
std::cout << GridLogIRL <<" -- total Nm = " << Nm <<" vectors"<< std::endl;
|
||||||
std::cout << GridLogMessage <<" -- accept Nstop = " << Nstop <<" vectors"<< std::endl;
|
std::cout << GridLogIRL <<" -- size of eval = " << eval.size() << std::endl;
|
||||||
std::cout << GridLogMessage <<" -- total Nm = " << Nm <<" vectors"<< std::endl;
|
std::cout << GridLogIRL <<" -- size of evec = " << evec.size() << std::endl;
|
||||||
std::cout << GridLogMessage <<" -- size of eval = " << eval.size() << std::endl;
|
|
||||||
std::cout << GridLogMessage <<" -- size of evec = " << evec.size() << std::endl;
|
|
||||||
if ( diagonalisation == IRLdiagonaliseWithDSTEGR ) {
|
if ( diagonalisation == IRLdiagonaliseWithDSTEGR ) {
|
||||||
std::cout << GridLogMessage << "Diagonalisation is DSTEGR "<<std::endl;
|
std::cout << GridLogIRL << "Diagonalisation is DSTEGR "<<std::endl;
|
||||||
} else if ( diagonalisation == IRLdiagonaliseWithQR ) {
|
} else if ( diagonalisation == IRLdiagonaliseWithQR ) {
|
||||||
std::cout << GridLogMessage << "Diagonalisation is QR "<<std::endl;
|
std::cout << GridLogIRL << "Diagonalisation is QR "<<std::endl;
|
||||||
} else if ( diagonalisation == IRLdiagonaliseWithEigen ) {
|
} else if ( diagonalisation == IRLdiagonaliseWithEigen ) {
|
||||||
std::cout << GridLogMessage << "Diagonalisation is Eigen "<<std::endl;
|
std::cout << GridLogIRL << "Diagonalisation is Eigen "<<std::endl;
|
||||||
}
|
}
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
std::cout << GridLogIRL <<"**************************************************************************"<< std::endl;
|
||||||
|
|
||||||
assert(Nm == evec.size() && Nm == eval.size());
|
assert(Nm <= evec.size() && Nm <= eval.size());
|
||||||
|
|
||||||
|
// quickly get an idea of the largest eigenvalue to more properly normalize the residuum
|
||||||
|
RealD evalMaxApprox = 0.0;
|
||||||
|
{
|
||||||
|
auto src_n = src;
|
||||||
|
auto tmp = src;
|
||||||
|
const int _MAX_ITER_IRL_MEVAPP_ = 50;
|
||||||
|
for (int i=0;i<_MAX_ITER_IRL_MEVAPP_;i++) {
|
||||||
|
normalise(src_n);
|
||||||
|
_HermOp(src_n,tmp);
|
||||||
|
RealD vnum = real(innerProduct(src_n,tmp)); // HermOp.
|
||||||
|
RealD vden = norm2(src_n);
|
||||||
|
RealD na = vnum/vden;
|
||||||
|
if (fabs(evalMaxApprox/na - 1.0) < 0.05)
|
||||||
|
i=_MAX_ITER_IRL_MEVAPP_;
|
||||||
|
evalMaxApprox = na;
|
||||||
|
std::cout << GridLogIRL << " Approximation of largest eigenvalue: " << evalMaxApprox << std::endl;
|
||||||
|
src_n = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<RealD> lme(Nm);
|
std::vector<RealD> lme(Nm);
|
||||||
std::vector<RealD> lme2(Nm);
|
std::vector<RealD> lme2(Nm);
|
||||||
std::vector<RealD> eval2(Nm);
|
std::vector<RealD> eval2(Nm);
|
||||||
|
std::vector<RealD> eval2_copy(Nm);
|
||||||
Eigen::MatrixXd Qt = Eigen::MatrixXd::Zero(Nm,Nm);
|
Eigen::MatrixXd Qt = Eigen::MatrixXd::Zero(Nm,Nm);
|
||||||
|
|
||||||
std::vector<int> Iconv(Nm);
|
|
||||||
std::vector<Field> B(Nm,grid); // waste of space replicating
|
|
||||||
|
|
||||||
Field f(grid);
|
Field f(grid);
|
||||||
Field v(grid);
|
Field v(grid);
|
||||||
|
|
||||||
int k1 = 1;
|
int k1 = 1;
|
||||||
int k2 = Nk;
|
int k2 = Nk;
|
||||||
|
RealD beta_k;
|
||||||
|
|
||||||
Nconv = 0;
|
Nconv = 0;
|
||||||
|
|
||||||
RealD beta_k;
|
|
||||||
|
|
||||||
// Set initial vector
|
// Set initial vector
|
||||||
evec[0] = src;
|
evec[0] = src;
|
||||||
std::cout << GridLogMessage <<"norm2(src)= " << norm2(src)<<std::endl;
|
|
||||||
|
|
||||||
normalise(evec[0]);
|
normalise(evec[0]);
|
||||||
std::cout << GridLogMessage <<"norm2(evec[0])= " << norm2(evec[0]) <<std::endl;
|
|
||||||
|
|
||||||
// Initial Nk steps
|
// Initial Nk steps
|
||||||
|
OrthoTime=0.;
|
||||||
for(int k=0; k<Nk; ++k) step(eval,lme,evec,f,Nm,k);
|
for(int k=0; k<Nk; ++k) step(eval,lme,evec,f,Nm,k);
|
||||||
|
std::cout<<GridLogIRL <<"Initial "<< Nk <<"steps done "<<std::endl;
|
||||||
|
std::cout<<GridLogIRL <<"Initial steps:OrthoTime "<<OrthoTime<< "seconds"<<std::endl;
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
// Restarting loop begins
|
// Restarting loop begins
|
||||||
|
//////////////////////////////////
|
||||||
int iter;
|
int iter;
|
||||||
for(iter = 0; iter<MaxIter; ++iter){
|
for(iter = 0; iter<MaxIter; ++iter){
|
||||||
|
|
||||||
|
OrthoTime=0.;
|
||||||
|
|
||||||
std::cout<< GridLogMessage <<" **********************"<< std::endl;
|
std::cout<< GridLogMessage <<" **********************"<< std::endl;
|
||||||
std::cout<< GridLogMessage <<" Restart iteration = "<< iter << std::endl;
|
std::cout<< GridLogMessage <<" Restart iteration = "<< iter << std::endl;
|
||||||
std::cout<< GridLogMessage <<" **********************"<< std::endl;
|
std::cout<< GridLogMessage <<" **********************"<< std::endl;
|
||||||
|
|
||||||
|
std::cout<<GridLogIRL <<" running "<<Nm-Nk <<" steps: "<<std::endl;
|
||||||
for(int k=Nk; k<Nm; ++k) step(eval,lme,evec,f,Nm,k);
|
for(int k=Nk; k<Nm; ++k) step(eval,lme,evec,f,Nm,k);
|
||||||
|
|
||||||
f *= lme[Nm-1];
|
f *= lme[Nm-1];
|
||||||
|
|
||||||
|
std::cout<<GridLogIRL <<" "<<Nm-Nk <<" steps done "<<std::endl;
|
||||||
|
std::cout<<GridLogIRL <<"Initial steps:OrthoTime "<<OrthoTime<< "seconds"<<std::endl;
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
// getting eigenvalues
|
// getting eigenvalues
|
||||||
|
//////////////////////////////////
|
||||||
for(int k=0; k<Nm; ++k){
|
for(int k=0; k<Nm; ++k){
|
||||||
eval2[k] = eval[k+k1-1];
|
eval2[k] = eval[k+k1-1];
|
||||||
lme2[k] = lme[k+k1-1];
|
lme2[k] = lme[k+k1-1];
|
||||||
}
|
}
|
||||||
Qt = Eigen::MatrixXd::Identity(Nm,Nm);
|
Qt = Eigen::MatrixXd::Identity(Nm,Nm);
|
||||||
diagonalize(eval2,lme2,Nm,Nm,Qt,grid);
|
diagonalize(eval2,lme2,Nm,Nm,Qt,grid);
|
||||||
|
std::cout<<GridLogIRL <<" diagonalized "<<std::endl;
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
// sorting
|
// sorting
|
||||||
_sort.push(eval2,Nm);
|
//////////////////////////////////
|
||||||
|
eval2_copy = eval2;
|
||||||
|
std::partial_sort(eval2.begin(),eval2.begin()+Nm,eval2.end(),std::greater<RealD>());
|
||||||
|
std::cout<<GridLogIRL <<" evals sorted "<<std::endl;
|
||||||
|
const int chunk=8;
|
||||||
|
for(int io=0; io<k2;io+=chunk){
|
||||||
|
std::cout<<GridLogIRL << "eval "<< std::setw(3) << io ;
|
||||||
|
for(int ii=0;ii<chunk;ii++){
|
||||||
|
if ( (io+ii)<k2 )
|
||||||
|
std::cout<< " "<< std::setw(12)<< eval2[io+ii];
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
// Implicitly shifted QR transformations
|
// Implicitly shifted QR transformations
|
||||||
|
//////////////////////////////////
|
||||||
Qt = Eigen::MatrixXd::Identity(Nm,Nm);
|
Qt = Eigen::MatrixXd::Identity(Nm,Nm);
|
||||||
for(int ip=k2; ip<Nm; ++ip){
|
for(int ip=k2; ip<Nm; ++ip){
|
||||||
// Eigen replacement for qr_decomp ???
|
QR_decomp(eval,lme,Nm,Nm,Qt,eval2[ip],k1,Nm);
|
||||||
qr_decomp(eval,lme,Nm,Nm,Qt,eval2[ip],k1,Nm);
|
|
||||||
}
|
}
|
||||||
|
std::cout<<GridLogIRL <<"QR decomposed "<<std::endl;
|
||||||
|
|
||||||
for(int i=0; i<(Nk+1); ++i) B[i] = 0.0;
|
assert(k2<Nm); assert(k2<Nm); assert(k1>0);
|
||||||
|
|
||||||
for(int j=k1-1; j<k2+1; ++j){
|
basisRotate(evec,Qt,k1-1,k2+1,0,Nm,Nm); /// big constraint on the basis
|
||||||
for(int k=0; k<Nm; ++k){
|
std::cout<<GridLogIRL <<"basisRotated by Qt"<<std::endl;
|
||||||
B[j].checkerboard = evec[k].checkerboard;
|
|
||||||
B[j] += Qt(j,k) * evec[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(int j=k1-1; j<k2+1; ++j) evec[j] = B[j];
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
// Compressed vector f and beta(k2)
|
// Compressed vector f and beta(k2)
|
||||||
|
////////////////////////////////////////////////////
|
||||||
f *= Qt(k2-1,Nm-1);
|
f *= Qt(k2-1,Nm-1);
|
||||||
f += lme[k2-1] * evec[k2];
|
f += lme[k2-1] * evec[k2];
|
||||||
beta_k = norm2(f);
|
beta_k = norm2(f);
|
||||||
beta_k = sqrt(beta_k);
|
beta_k = sqrt(beta_k);
|
||||||
std::cout<< GridLogMessage<<" beta(k) = "<<beta_k<<std::endl;
|
std::cout<<GridLogIRL<<" beta(k) = "<<beta_k<<std::endl;
|
||||||
|
|
||||||
RealD betar = 1.0/beta_k;
|
RealD betar = 1.0/beta_k;
|
||||||
evec[k2] = betar * f;
|
evec[k2] = betar * f;
|
||||||
lme[k2-1] = beta_k;
|
lme[k2-1] = beta_k;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
// Convergence test
|
// Convergence test
|
||||||
|
////////////////////////////////////////////////////
|
||||||
for(int k=0; k<Nm; ++k){
|
for(int k=0; k<Nm; ++k){
|
||||||
eval2[k] = eval[k];
|
eval2[k] = eval[k];
|
||||||
lme2[k] = lme[k];
|
lme2[k] = lme[k];
|
||||||
}
|
}
|
||||||
Qt = Eigen::MatrixXd::Identity(Nm,Nm);
|
Qt = Eigen::MatrixXd::Identity(Nm,Nm);
|
||||||
diagonalize(eval2,lme2,Nk,Nm,Qt,grid);
|
diagonalize(eval2,lme2,Nk,Nm,Qt,grid);
|
||||||
|
std::cout<<GridLogIRL <<" Diagonalized "<<std::endl;
|
||||||
for(int k = 0; k<Nk; ++k) B[k]=0.0;
|
|
||||||
|
|
||||||
for(int j = 0; j<Nk; ++j){
|
|
||||||
for(int k = 0; k<Nk; ++k){
|
|
||||||
B[j].checkerboard = evec[k].checkerboard;
|
|
||||||
B[j] += Qt(j,k) * evec[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Nconv = 0;
|
Nconv = 0;
|
||||||
for(int i=0; i<Nk; ++i){
|
if (iter >= MinRestart) {
|
||||||
|
|
||||||
_Linop.HermOp(B[i],v);
|
std::cout << GridLogIRL << "Test convergence: rotate subset of vectors to test convergence " << std::endl;
|
||||||
|
|
||||||
RealD vnum = real(innerProduct(B[i],v)); // HermOp.
|
Field B(grid); B.checkerboard = evec[0].checkerboard;
|
||||||
RealD vden = norm2(B[i]);
|
|
||||||
eval2[i] = vnum/vden;
|
|
||||||
v -= eval2[i]*B[i];
|
|
||||||
RealD vv = norm2(v);
|
|
||||||
|
|
||||||
std::cout.precision(13);
|
// power of two search pattern; not every evalue in eval2 is assessed.
|
||||||
std::cout << GridLogMessage << "[" << std::setw(3)<< std::setiosflags(std::ios_base::right) <<i<<"] ";
|
int allconv =1;
|
||||||
std::cout << "eval = "<<std::setw(25)<< std::setiosflags(std::ios_base::left)<< eval2[i];
|
for(int jj = 1; jj<=Nstop; jj*=2){
|
||||||
std::cout << " |H B[i] - eval[i]B[i]|^2 "<< std::setw(25)<< std::setiosflags(std::ios_base::right)<< vv<< std::endl;
|
int j = Nstop-jj;
|
||||||
|
RealD e = eval2_copy[j]; // Discard the evalue
|
||||||
|
basisRotateJ(B,evec,Qt,j,0,Nk,Nm);
|
||||||
|
if( !_Tester.TestConvergence(j,eresid,B,e,evalMaxApprox) ) {
|
||||||
|
allconv=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Do evec[0] for good measure
|
||||||
|
{
|
||||||
|
int j=0;
|
||||||
|
RealD e = eval2_copy[0];
|
||||||
|
basisRotateJ(B,evec,Qt,j,0,Nk,Nm);
|
||||||
|
if( !_Tester.TestConvergence(j,eresid,B,e,evalMaxApprox) ) allconv=0;
|
||||||
|
}
|
||||||
|
if ( allconv ) Nconv = Nstop;
|
||||||
|
|
||||||
// change the criteria as evals are supposed to be sorted, all evals smaller(larger) than Nstop should have converged
|
// test if we converged, if so, terminate
|
||||||
if((vv<eresid*eresid) && (i == Nconv) ){
|
std::cout<<GridLogIRL<<" #modes converged: >= "<<Nconv<<"/"<<Nstop<<std::endl;
|
||||||
Iconv[Nconv] = i;
|
// if( Nconv>=Nstop || beta_k < betastp){
|
||||||
++Nconv;
|
if( Nconv>=Nstop){
|
||||||
|
goto converged;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // i-loop end
|
} else {
|
||||||
|
std::cout << GridLogIRL << "iter < MinRestart: do not yet test for convergence\n";
|
||||||
|
} // end of iter loop
|
||||||
|
}
|
||||||
|
|
||||||
std::cout<< GridLogMessage <<" #modes converged: "<<Nconv<<std::endl;
|
std::cout<<GridLogError<<"\n NOT converged.\n";
|
||||||
|
|
||||||
if( Nconv>=Nstop ){
|
|
||||||
goto converged;
|
|
||||||
}
|
|
||||||
} // end of iter loop
|
|
||||||
|
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
|
||||||
std::cout<< GridLogError <<" ImplicitlyRestartedLanczos::calc() NOT converged.";
|
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
converged:
|
converged:
|
||||||
// Sorting
|
{
|
||||||
eval.resize(Nconv);
|
Field B(grid); B.checkerboard = evec[0].checkerboard;
|
||||||
evec.resize(Nconv,grid);
|
basisRotate(evec,Qt,0,Nk,0,Nk,Nm);
|
||||||
for(int i=0; i<Nconv; ++i){
|
std::cout << GridLogIRL << " Rotated basis"<<std::endl;
|
||||||
eval[i] = eval2[Iconv[i]];
|
Nconv=0;
|
||||||
evec[i] = B[Iconv[i]];
|
//////////////////////////////////////////////////////////////////////
|
||||||
}
|
// Full final convergence test; unconditionally applied
|
||||||
_sort.push(eval,evec,Nconv);
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
for(int j = 0; j<=Nk; j++){
|
||||||
|
B=evec[j];
|
||||||
|
if( _Tester.ReconstructEval(j,eresid,B,eval2[j],evalMaxApprox) ) {
|
||||||
|
Nconv++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
if ( Nconv < Nstop )
|
||||||
std::cout << GridLogMessage << "ImplicitlyRestartedLanczos CONVERGED ; Summary :\n";
|
std::cout << GridLogIRL << "Nconv ("<<Nconv<<") < Nstop ("<<Nstop<<")"<<std::endl;
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
|
||||||
std::cout << GridLogMessage << " -- Iterations = "<< iter << "\n";
|
eval=eval2;
|
||||||
std::cout << GridLogMessage << " -- beta(k) = "<< beta_k << "\n";
|
|
||||||
std::cout << GridLogMessage << " -- Nconv = "<< Nconv << "\n";
|
//Keep only converged
|
||||||
std::cout << GridLogMessage <<"**************************************************************************"<< std::endl;
|
eval.resize(Nconv);// Nstop?
|
||||||
|
evec.resize(Nconv,grid);// Nstop?
|
||||||
|
basisSortInPlace(evec,eval,reverse);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << GridLogIRL <<"**************************************************************************"<< std::endl;
|
||||||
|
std::cout << GridLogIRL << "ImplicitlyRestartedLanczos CONVERGED ; Summary :\n";
|
||||||
|
std::cout << GridLogIRL <<"**************************************************************************"<< std::endl;
|
||||||
|
std::cout << GridLogIRL << " -- Iterations = "<< iter << "\n";
|
||||||
|
std::cout << GridLogIRL << " -- beta(k) = "<< beta_k << "\n";
|
||||||
|
std::cout << GridLogIRL << " -- Nconv = "<< Nconv << "\n";
|
||||||
|
std::cout << GridLogIRL <<"**************************************************************************"<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Saad PP. 195
|
/* Saad PP. 195
|
||||||
1. Choose an initial vector v1 of 2-norm unity. Set β1 ≡ 0, v0 ≡ 0
|
1. Choose an initial vector v1 of 2-norm unity. Set β1 ≡ 0, v0 ≡ 0
|
||||||
2. For k = 1,2,...,m Do:
|
2. For k = 1,2,...,m Do:
|
||||||
@ -361,14 +568,18 @@ private:
|
|||||||
const RealD tiny = 1.0e-20;
|
const RealD tiny = 1.0e-20;
|
||||||
assert( k< Nm );
|
assert( k< Nm );
|
||||||
|
|
||||||
_poly(_Linop,evec[k],w); // 3. wk:=Avk−βkv_{k−1}
|
GridStopWatch gsw_op,gsw_o;
|
||||||
|
|
||||||
|
Field& evec_k = evec[k];
|
||||||
|
|
||||||
|
_PolyOp(evec_k,w); std::cout<<GridLogIRL << "PolyOp" <<std::endl;
|
||||||
|
|
||||||
if(k>0) w -= lme[k-1] * evec[k-1];
|
if(k>0) w -= lme[k-1] * evec[k-1];
|
||||||
|
|
||||||
ComplexD zalph = innerProduct(evec[k],w); // 4. αk:=(wk,vk)
|
ComplexD zalph = innerProduct(evec_k,w); // 4. αk:=(wk,vk)
|
||||||
RealD alph = real(zalph);
|
RealD alph = real(zalph);
|
||||||
|
|
||||||
w = w - alph * evec[k];// 5. wk:=wk−αkvk
|
w = w - alph * evec_k;// 5. wk:=wk−αkvk
|
||||||
|
|
||||||
RealD beta = normalise(w); // 6. βk+1 := ∥wk∥2. If βk+1 = 0 then Stop
|
RealD beta = normalise(w); // 6. βk+1 := ∥wk∥2. If βk+1 = 0 then Stop
|
||||||
// 7. vk+1 := wk/βk+1
|
// 7. vk+1 := wk/βk+1
|
||||||
@ -376,10 +587,16 @@ private:
|
|||||||
lmd[k] = alph;
|
lmd[k] = alph;
|
||||||
lme[k] = beta;
|
lme[k] = beta;
|
||||||
|
|
||||||
if ( k > 0 ) orthogonalize(w,evec,k); // orthonormalise
|
if (k>0 && k % orth_period == 0) {
|
||||||
if ( k < Nm-1) evec[k+1] = w;
|
orthogonalize(w,evec,k); // orthonormalise
|
||||||
|
std::cout<<GridLogIRL << "Orthogonalised " <<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
if ( beta < tiny ) std::cout << GridLogMessage << " beta is tiny "<<beta<<std::endl;
|
if(k < Nm-1) evec[k+1] = w;
|
||||||
|
|
||||||
|
std::cout<<GridLogIRL << "alpha[" << k << "] = " << zalph << " beta[" << k << "] = "<<beta<<std::endl;
|
||||||
|
if ( beta < tiny )
|
||||||
|
std::cout<<GridLogIRL << " beta is tiny "<<beta<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void diagonalize_Eigen(std::vector<RealD>& lmd, std::vector<RealD>& lme,
|
void diagonalize_Eigen(std::vector<RealD>& lmd, std::vector<RealD>& lme,
|
||||||
@ -404,11 +621,11 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// File could end here if settle on Eigen ???
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void qr_decomp(std::vector<RealD>& lmd, // Nm
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// File could end here if settle on Eigen ??? !!!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
void QR_decomp(std::vector<RealD>& lmd, // Nm
|
||||||
std::vector<RealD>& lme, // Nm
|
std::vector<RealD>& lme, // Nm
|
||||||
int Nk, int Nm, // Nk, Nm
|
int Nk, int Nm, // Nk, Nm
|
||||||
Eigen::MatrixXd& Qt, // Nm x Nm matrix
|
Eigen::MatrixXd& Qt, // Nm x Nm matrix
|
||||||
@ -575,51 +792,50 @@ void diagonalize_lapack(std::vector<RealD>& lmd,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void diagonalize_QR(std::vector<RealD>& lmd, std::vector<RealD>& lme,
|
void diagonalize_QR(std::vector<RealD>& lmd, std::vector<RealD>& lme,
|
||||||
int Nk, int Nm,
|
int Nk, int Nm,
|
||||||
Eigen::MatrixXd & Qt,
|
Eigen::MatrixXd & Qt,
|
||||||
GridBase *grid)
|
GridBase *grid)
|
||||||
{
|
{
|
||||||
int Niter = 100*Nm;
|
int QRiter = 100*Nm;
|
||||||
int kmin = 1;
|
int kmin = 1;
|
||||||
int kmax = Nk;
|
int kmax = Nk;
|
||||||
|
|
||||||
// (this should be more sophisticated)
|
// (this should be more sophisticated)
|
||||||
for(int iter=0; iter<Niter; ++iter){
|
for(int iter=0; iter<QRiter; ++iter){
|
||||||
|
|
||||||
// determination of 2x2 leading submatrix
|
// determination of 2x2 leading submatrix
|
||||||
RealD dsub = lmd[kmax-1]-lmd[kmax-2];
|
RealD dsub = lmd[kmax-1]-lmd[kmax-2];
|
||||||
RealD dd = sqrt(dsub*dsub + 4.0*lme[kmax-2]*lme[kmax-2]);
|
RealD dd = sqrt(dsub*dsub + 4.0*lme[kmax-2]*lme[kmax-2]);
|
||||||
RealD Dsh = 0.5*(lmd[kmax-2]+lmd[kmax-1] +dd*(dsub/fabs(dsub)));
|
RealD Dsh = 0.5*(lmd[kmax-2]+lmd[kmax-1] +dd*(dsub/fabs(dsub)));
|
||||||
// (Dsh: shift)
|
// (Dsh: shift)
|
||||||
|
|
||||||
// transformation
|
// transformation
|
||||||
qr_decomp(lmd,lme,Nk,Nm,Qt,Dsh,kmin,kmax); // Nk, Nm
|
QR_decomp(lmd,lme,Nk,Nm,Qt,Dsh,kmin,kmax); // Nk, Nm
|
||||||
|
|
||||||
// Convergence criterion (redef of kmin and kamx)
|
// Convergence criterion (redef of kmin and kamx)
|
||||||
for(int j=kmax-1; j>= kmin; --j){
|
for(int j=kmax-1; j>= kmin; --j){
|
||||||
RealD dds = fabs(lmd[j-1])+fabs(lmd[j]);
|
RealD dds = fabs(lmd[j-1])+fabs(lmd[j]);
|
||||||
if(fabs(lme[j-1])+dds > dds){
|
if(fabs(lme[j-1])+dds > dds){
|
||||||
kmax = j+1;
|
kmax = j+1;
|
||||||
goto continued;
|
goto continued;
|
||||||
}
|
|
||||||
}
|
|
||||||
Niter = iter;
|
|
||||||
return;
|
|
||||||
|
|
||||||
continued:
|
|
||||||
for(int j=0; j<kmax-1; ++j){
|
|
||||||
RealD dds = fabs(lmd[j])+fabs(lmd[j+1]);
|
|
||||||
if(fabs(lme[j])+dds > dds){
|
|
||||||
kmin = j+1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << GridLogError << "[QL method] Error - Too many iteration: "<<Niter<<"\n";
|
QRiter = iter;
|
||||||
abort();
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
};
|
continued:
|
||||||
|
for(int j=0; j<kmax-1; ++j){
|
||||||
|
RealD dds = fabs(lmd[j])+fabs(lmd[j+1]);
|
||||||
|
if(fabs(lme[j])+dds > dds){
|
||||||
|
kmin = j+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << GridLogError << "[QL method] Error - Too many iteration: "<<QRiter<<"\n";
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
404
lib/algorithms/iterative/LocalCoherenceLanczos.h
Normal file
404
lib/algorithms/iterative/LocalCoherenceLanczos.h
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./lib/algorithms/iterative/LocalCoherenceLanczos.h
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Christoph Lehner <clehner@bnl.gov>
|
||||||
|
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef GRID_LOCAL_COHERENCE_IRL_H
|
||||||
|
#define GRID_LOCAL_COHERENCE_IRL_H
|
||||||
|
|
||||||
|
namespace Grid {
|
||||||
|
|
||||||
|
|
||||||
|
struct LanczosParams : Serializable {
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LanczosParams,
|
||||||
|
ChebyParams, Cheby,/*Chebyshev*/
|
||||||
|
int, Nstop, /*Vecs in Lanczos must converge Nstop < Nk < Nm*/
|
||||||
|
int, Nk, /*Vecs in Lanczos seek converge*/
|
||||||
|
int, Nm, /*Total vecs in Lanczos include restart*/
|
||||||
|
RealD, resid, /*residual*/
|
||||||
|
int, MaxIt,
|
||||||
|
RealD, betastp, /* ? */
|
||||||
|
int, MinRes); // Must restart
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LocalCoherenceLanczosParams : Serializable {
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LocalCoherenceLanczosParams,
|
||||||
|
bool, saveEvecs,
|
||||||
|
bool, doFine,
|
||||||
|
bool, doFineRead,
|
||||||
|
bool, doCoarse,
|
||||||
|
bool, doCoarseRead,
|
||||||
|
LanczosParams, FineParams,
|
||||||
|
LanczosParams, CoarseParams,
|
||||||
|
ChebyParams, Smoother,
|
||||||
|
RealD , coarse_relax_tol,
|
||||||
|
std::vector<int>, blockSize,
|
||||||
|
std::string, config,
|
||||||
|
std::vector < std::complex<double> >, omega,
|
||||||
|
RealD, mass,
|
||||||
|
RealD, M5);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Duplicate functionality; ProjectedFunctionHermOp could be used with the trivial function
|
||||||
|
template<class Fobj,class CComplex,int nbasis>
|
||||||
|
class ProjectedHermOp : public LinearFunction<Lattice<iVector<CComplex,nbasis > > > {
|
||||||
|
public:
|
||||||
|
typedef iVector<CComplex,nbasis > CoarseSiteVector;
|
||||||
|
typedef Lattice<CoarseSiteVector> CoarseField;
|
||||||
|
typedef Lattice<CComplex> CoarseScalar; // used for inner products on fine field
|
||||||
|
typedef Lattice<Fobj> FineField;
|
||||||
|
|
||||||
|
LinearOperatorBase<FineField> &_Linop;
|
||||||
|
std::vector<FineField> &subspace;
|
||||||
|
|
||||||
|
ProjectedHermOp(LinearOperatorBase<FineField>& linop, std::vector<FineField> & _subspace) :
|
||||||
|
_Linop(linop), subspace(_subspace)
|
||||||
|
{
|
||||||
|
assert(subspace.size() >0);
|
||||||
|
};
|
||||||
|
|
||||||
|
void operator()(const CoarseField& in, CoarseField& out) {
|
||||||
|
GridBase *FineGrid = subspace[0]._grid;
|
||||||
|
int checkerboard = subspace[0].checkerboard;
|
||||||
|
|
||||||
|
FineField fin (FineGrid); fin.checkerboard= checkerboard;
|
||||||
|
FineField fout(FineGrid); fout.checkerboard = checkerboard;
|
||||||
|
|
||||||
|
blockPromote(in,fin,subspace); std::cout<<GridLogIRL<<"ProjectedHermop : Promote to fine"<<std::endl;
|
||||||
|
_Linop.HermOp(fin,fout); std::cout<<GridLogIRL<<"ProjectedHermop : HermOp (fine) "<<std::endl;
|
||||||
|
blockProject(out,fout,subspace); std::cout<<GridLogIRL<<"ProjectedHermop : Project to coarse "<<std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Fobj,class CComplex,int nbasis>
|
||||||
|
class ProjectedFunctionHermOp : public LinearFunction<Lattice<iVector<CComplex,nbasis > > > {
|
||||||
|
public:
|
||||||
|
typedef iVector<CComplex,nbasis > CoarseSiteVector;
|
||||||
|
typedef Lattice<CoarseSiteVector> CoarseField;
|
||||||
|
typedef Lattice<CComplex> CoarseScalar; // used for inner products on fine field
|
||||||
|
typedef Lattice<Fobj> FineField;
|
||||||
|
|
||||||
|
|
||||||
|
OperatorFunction<FineField> & _poly;
|
||||||
|
LinearOperatorBase<FineField> &_Linop;
|
||||||
|
std::vector<FineField> &subspace;
|
||||||
|
|
||||||
|
ProjectedFunctionHermOp(OperatorFunction<FineField> & poly,
|
||||||
|
LinearOperatorBase<FineField>& linop,
|
||||||
|
std::vector<FineField> & _subspace) :
|
||||||
|
_poly(poly),
|
||||||
|
_Linop(linop),
|
||||||
|
subspace(_subspace)
|
||||||
|
{ };
|
||||||
|
|
||||||
|
void operator()(const CoarseField& in, CoarseField& out) {
|
||||||
|
|
||||||
|
GridBase *FineGrid = subspace[0]._grid;
|
||||||
|
int checkerboard = subspace[0].checkerboard;
|
||||||
|
|
||||||
|
FineField fin (FineGrid); fin.checkerboard =checkerboard;
|
||||||
|
FineField fout(FineGrid);fout.checkerboard =checkerboard;
|
||||||
|
|
||||||
|
blockPromote(in,fin,subspace); std::cout<<GridLogIRL<<"ProjectedFunctionHermop : Promote to fine"<<std::endl;
|
||||||
|
_poly(_Linop,fin,fout); std::cout<<GridLogIRL<<"ProjectedFunctionHermop : Poly "<<std::endl;
|
||||||
|
blockProject(out,fout,subspace); std::cout<<GridLogIRL<<"ProjectedFunctionHermop : Project to coarse "<<std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Fobj,class CComplex,int nbasis>
|
||||||
|
class ImplicitlyRestartedLanczosSmoothedTester : public ImplicitlyRestartedLanczosTester<Lattice<iVector<CComplex,nbasis > > >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef iVector<CComplex,nbasis > CoarseSiteVector;
|
||||||
|
typedef Lattice<CoarseSiteVector> CoarseField;
|
||||||
|
typedef Lattice<CComplex> CoarseScalar; // used for inner products on fine field
|
||||||
|
typedef Lattice<Fobj> FineField;
|
||||||
|
|
||||||
|
LinearFunction<CoarseField> & _Poly;
|
||||||
|
OperatorFunction<FineField> & _smoother;
|
||||||
|
LinearOperatorBase<FineField> &_Linop;
|
||||||
|
RealD _coarse_relax_tol;
|
||||||
|
std::vector<FineField> &_subspace;
|
||||||
|
|
||||||
|
ImplicitlyRestartedLanczosSmoothedTester(LinearFunction<CoarseField> &Poly,
|
||||||
|
OperatorFunction<FineField> &smoother,
|
||||||
|
LinearOperatorBase<FineField> &Linop,
|
||||||
|
std::vector<FineField> &subspace,
|
||||||
|
RealD coarse_relax_tol=5.0e3)
|
||||||
|
: _smoother(smoother), _Linop(Linop), _Poly(Poly), _subspace(subspace),
|
||||||
|
_coarse_relax_tol(coarse_relax_tol)
|
||||||
|
{ };
|
||||||
|
|
||||||
|
int TestConvergence(int j,RealD eresid,CoarseField &B, RealD &eval,RealD evalMaxApprox)
|
||||||
|
{
|
||||||
|
CoarseField v(B);
|
||||||
|
RealD eval_poly = eval;
|
||||||
|
|
||||||
|
// Apply operator
|
||||||
|
_Poly(B,v);
|
||||||
|
|
||||||
|
RealD vnum = real(innerProduct(B,v)); // HermOp.
|
||||||
|
RealD vden = norm2(B);
|
||||||
|
RealD vv0 = norm2(v);
|
||||||
|
eval = vnum/vden;
|
||||||
|
v -= eval*B;
|
||||||
|
|
||||||
|
RealD vv = norm2(v) / ::pow(evalMaxApprox,2.0);
|
||||||
|
|
||||||
|
std::cout.precision(13);
|
||||||
|
std::cout<<GridLogIRL << "[" << std::setw(3)<<j<<"] "
|
||||||
|
<<"eval = "<<std::setw(25)<< eval << " (" << eval_poly << ")"
|
||||||
|
<<" |H B[i] - eval[i]B[i]|^2 / evalMaxApprox^2 " << std::setw(25) << vv
|
||||||
|
<<std::endl;
|
||||||
|
|
||||||
|
int conv=0;
|
||||||
|
if( (vv<eresid*eresid) ) conv = 1;
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
int ReconstructEval(int j,RealD eresid,CoarseField &B, RealD &eval,RealD evalMaxApprox)
|
||||||
|
{
|
||||||
|
GridBase *FineGrid = _subspace[0]._grid;
|
||||||
|
int checkerboard = _subspace[0].checkerboard;
|
||||||
|
FineField fB(FineGrid);fB.checkerboard =checkerboard;
|
||||||
|
FineField fv(FineGrid);fv.checkerboard =checkerboard;
|
||||||
|
|
||||||
|
blockPromote(B,fv,_subspace);
|
||||||
|
|
||||||
|
_smoother(_Linop,fv,fB);
|
||||||
|
|
||||||
|
RealD eval_poly = eval;
|
||||||
|
_Linop.HermOp(fB,fv);
|
||||||
|
|
||||||
|
RealD vnum = real(innerProduct(fB,fv)); // HermOp.
|
||||||
|
RealD vden = norm2(fB);
|
||||||
|
RealD vv0 = norm2(fv);
|
||||||
|
eval = vnum/vden;
|
||||||
|
fv -= eval*fB;
|
||||||
|
RealD vv = norm2(fv) / ::pow(evalMaxApprox,2.0);
|
||||||
|
|
||||||
|
std::cout.precision(13);
|
||||||
|
std::cout<<GridLogIRL << "[" << std::setw(3)<<j<<"] "
|
||||||
|
<<"eval = "<<std::setw(25)<< eval << " (" << eval_poly << ")"
|
||||||
|
<<" |H B[i] - eval[i]B[i]|^2 / evalMaxApprox^2 " << std::setw(25) << vv
|
||||||
|
<<std::endl;
|
||||||
|
if ( j > nbasis ) eresid = eresid*_coarse_relax_tol;
|
||||||
|
if( (vv<eresid*eresid) ) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Make serializable Lanczos params
|
||||||
|
////////////////////////////////////////////
|
||||||
|
template<class Fobj,class CComplex,int nbasis>
|
||||||
|
class LocalCoherenceLanczos
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef iVector<CComplex,nbasis > CoarseSiteVector;
|
||||||
|
typedef Lattice<CComplex> CoarseScalar; // used for inner products on fine field
|
||||||
|
typedef Lattice<CoarseSiteVector> CoarseField;
|
||||||
|
typedef Lattice<Fobj> FineField;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GridBase *_CoarseGrid;
|
||||||
|
GridBase *_FineGrid;
|
||||||
|
int _checkerboard;
|
||||||
|
LinearOperatorBase<FineField> & _FineOp;
|
||||||
|
|
||||||
|
std::vector<RealD> &evals_fine;
|
||||||
|
std::vector<RealD> &evals_coarse;
|
||||||
|
std::vector<FineField> &subspace;
|
||||||
|
std::vector<CoarseField> &evec_coarse;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<RealD> _evals_fine;
|
||||||
|
std::vector<RealD> _evals_coarse;
|
||||||
|
std::vector<FineField> _subspace;
|
||||||
|
std::vector<CoarseField> _evec_coarse;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LocalCoherenceLanczos(GridBase *FineGrid,
|
||||||
|
GridBase *CoarseGrid,
|
||||||
|
LinearOperatorBase<FineField> &FineOp,
|
||||||
|
int checkerboard) :
|
||||||
|
_CoarseGrid(CoarseGrid),
|
||||||
|
_FineGrid(FineGrid),
|
||||||
|
_FineOp(FineOp),
|
||||||
|
_checkerboard(checkerboard),
|
||||||
|
evals_fine (_evals_fine),
|
||||||
|
evals_coarse(_evals_coarse),
|
||||||
|
subspace (_subspace),
|
||||||
|
evec_coarse(_evec_coarse)
|
||||||
|
{
|
||||||
|
evals_fine.resize(0);
|
||||||
|
evals_coarse.resize(0);
|
||||||
|
};
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Alternate constructore, external storage for use by Hadrons module
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
LocalCoherenceLanczos(GridBase *FineGrid,
|
||||||
|
GridBase *CoarseGrid,
|
||||||
|
LinearOperatorBase<FineField> &FineOp,
|
||||||
|
int checkerboard,
|
||||||
|
std::vector<FineField> &ext_subspace,
|
||||||
|
std::vector<CoarseField> &ext_coarse,
|
||||||
|
std::vector<RealD> &ext_eval_fine,
|
||||||
|
std::vector<RealD> &ext_eval_coarse
|
||||||
|
) :
|
||||||
|
_CoarseGrid(CoarseGrid),
|
||||||
|
_FineGrid(FineGrid),
|
||||||
|
_FineOp(FineOp),
|
||||||
|
_checkerboard(checkerboard),
|
||||||
|
evals_fine (ext_eval_fine),
|
||||||
|
evals_coarse(ext_eval_coarse),
|
||||||
|
subspace (ext_subspace),
|
||||||
|
evec_coarse (ext_coarse)
|
||||||
|
{
|
||||||
|
evals_fine.resize(0);
|
||||||
|
evals_coarse.resize(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
void Orthogonalise(void ) {
|
||||||
|
CoarseScalar InnerProd(_CoarseGrid);
|
||||||
|
blockOrthogonalise(InnerProd,subspace);std::cout << GridLogMessage <<" Gramm-Schmidt pass 1"<<std::endl;
|
||||||
|
blockOrthogonalise(InnerProd,subspace);std::cout << GridLogMessage <<" Gramm-Schmidt pass 2"<<std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> static RealD normalise(T& v)
|
||||||
|
{
|
||||||
|
RealD nn = norm2(v);
|
||||||
|
nn = ::sqrt(nn);
|
||||||
|
v = v * (1.0/nn);
|
||||||
|
return nn;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void fakeFine(void)
|
||||||
|
{
|
||||||
|
int Nk = nbasis;
|
||||||
|
subspace.resize(Nk,_FineGrid);
|
||||||
|
subspace[0]=1.0;
|
||||||
|
subspace[0].checkerboard=_checkerboard;
|
||||||
|
normalise(subspace[0]);
|
||||||
|
PlainHermOp<FineField> Op(_FineOp);
|
||||||
|
for(int k=1;k<Nk;k++){
|
||||||
|
subspace[k].checkerboard=_checkerboard;
|
||||||
|
Op(subspace[k-1],subspace[k]);
|
||||||
|
normalise(subspace[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void testFine(RealD resid)
|
||||||
|
{
|
||||||
|
assert(evals_fine.size() == nbasis);
|
||||||
|
assert(subspace.size() == nbasis);
|
||||||
|
PlainHermOp<FineField> Op(_FineOp);
|
||||||
|
ImplicitlyRestartedLanczosHermOpTester<FineField> SimpleTester(Op);
|
||||||
|
for(int k=0;k<nbasis;k++){
|
||||||
|
assert(SimpleTester.ReconstructEval(k,resid,subspace[k],evals_fine[k],1.0)==1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testCoarse(RealD resid,ChebyParams cheby_smooth,RealD relax)
|
||||||
|
{
|
||||||
|
assert(evals_fine.size() == nbasis);
|
||||||
|
assert(subspace.size() == nbasis);
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// create a smoother and see if we can get a cheap convergence test and smooth inside the IRL
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Chebyshev<FineField> ChebySmooth(cheby_smooth);
|
||||||
|
ProjectedFunctionHermOp<Fobj,CComplex,nbasis> ChebyOp (ChebySmooth,_FineOp,_subspace);
|
||||||
|
ImplicitlyRestartedLanczosSmoothedTester<Fobj,CComplex,nbasis> ChebySmoothTester(ChebyOp,ChebySmooth,_FineOp,subspace,relax);
|
||||||
|
|
||||||
|
for(int k=0;k<evec_coarse.size();k++){
|
||||||
|
if ( k < nbasis ) {
|
||||||
|
assert(ChebySmoothTester.ReconstructEval(k,resid,evec_coarse[k],evals_coarse[k],1.0)==1);
|
||||||
|
} else {
|
||||||
|
assert(ChebySmoothTester.ReconstructEval(k,resid*relax,evec_coarse[k],evals_coarse[k],1.0)==1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void calcFine(ChebyParams cheby_parms,int Nstop,int Nk,int Nm,RealD resid,
|
||||||
|
RealD MaxIt, RealD betastp, int MinRes)
|
||||||
|
{
|
||||||
|
assert(nbasis<=Nm);
|
||||||
|
Chebyshev<FineField> Cheby(cheby_parms);
|
||||||
|
FunctionHermOp<FineField> ChebyOp(Cheby,_FineOp);
|
||||||
|
PlainHermOp<FineField> Op(_FineOp);
|
||||||
|
|
||||||
|
evals_fine.resize(Nm);
|
||||||
|
subspace.resize(Nm,_FineGrid);
|
||||||
|
|
||||||
|
ImplicitlyRestartedLanczos<FineField> IRL(ChebyOp,Op,Nstop,Nk,Nm,resid,MaxIt,betastp,MinRes);
|
||||||
|
|
||||||
|
FineField src(_FineGrid); src=1.0; src.checkerboard = _checkerboard;
|
||||||
|
|
||||||
|
int Nconv;
|
||||||
|
IRL.calc(evals_fine,subspace,src,Nconv,false);
|
||||||
|
|
||||||
|
// Shrink down to number saved
|
||||||
|
assert(Nstop>=nbasis);
|
||||||
|
assert(Nconv>=nbasis);
|
||||||
|
evals_fine.resize(nbasis);
|
||||||
|
subspace.resize(nbasis,_FineGrid);
|
||||||
|
}
|
||||||
|
void calcCoarse(ChebyParams cheby_op,ChebyParams cheby_smooth,RealD relax,
|
||||||
|
int Nstop, int Nk, int Nm,RealD resid,
|
||||||
|
RealD MaxIt, RealD betastp, int MinRes)
|
||||||
|
{
|
||||||
|
Chebyshev<FineField> Cheby(cheby_op);
|
||||||
|
ProjectedHermOp<Fobj,CComplex,nbasis> Op(_FineOp,_subspace);
|
||||||
|
ProjectedFunctionHermOp<Fobj,CComplex,nbasis> ChebyOp (Cheby,_FineOp,_subspace);
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// create a smoother and see if we can get a cheap convergence test and smooth inside the IRL
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Chebyshev<FineField> ChebySmooth(cheby_smooth);
|
||||||
|
ImplicitlyRestartedLanczosSmoothedTester<Fobj,CComplex,nbasis> ChebySmoothTester(ChebyOp,ChebySmooth,_FineOp,_subspace,relax);
|
||||||
|
|
||||||
|
evals_coarse.resize(Nm);
|
||||||
|
evec_coarse.resize(Nm,_CoarseGrid);
|
||||||
|
|
||||||
|
CoarseField src(_CoarseGrid); src=1.0;
|
||||||
|
|
||||||
|
ImplicitlyRestartedLanczos<CoarseField> IRL(ChebyOp,ChebyOp,ChebySmoothTester,Nstop,Nk,Nm,resid,MaxIt,betastp,MinRes);
|
||||||
|
int Nconv=0;
|
||||||
|
IRL.calc(evals_coarse,evec_coarse,src,Nconv,false);
|
||||||
|
assert(Nconv>=Nstop);
|
||||||
|
evals_coarse.resize(Nstop);
|
||||||
|
evec_coarse.resize (Nstop,_CoarseGrid);
|
||||||
|
for (int i=0;i<Nstop;i++){
|
||||||
|
std::cout << i << " Coarse eval = " << evals_coarse[i] << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
@ -53,16 +53,129 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
* M psi = eta
|
* M psi = eta
|
||||||
***********************
|
***********************
|
||||||
*Odd
|
*Odd
|
||||||
* i) (D_oo)^{\dag} D_oo psi_o = (D_oo)^dag L^{-1} eta_o
|
* i) D_oo psi_o = L^{-1} eta_o
|
||||||
* eta_o' = (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e)
|
* eta_o' = (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e)
|
||||||
|
*
|
||||||
|
* Wilson:
|
||||||
|
* (D_oo)^{\dag} D_oo psi_o = (D_oo)^dag L^{-1} eta_o
|
||||||
|
* Stag:
|
||||||
|
* D_oo psi_o = L^{-1} eta = (eta_o - Moe Mee^{-1} eta_e)
|
||||||
|
*
|
||||||
|
* L^-1 eta_o= (1 0 ) (e
|
||||||
|
* (-MoeMee^{-1} 1 )
|
||||||
|
*
|
||||||
*Even
|
*Even
|
||||||
* ii) Mee psi_e + Meo psi_o = src_e
|
* ii) Mee psi_e + Meo psi_o = src_e
|
||||||
*
|
*
|
||||||
* => sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
* => sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* TODO: Other options:
|
||||||
|
*
|
||||||
|
* a) change checkerboards for Schur e<->o
|
||||||
|
*
|
||||||
|
* Left precon by Moo^-1
|
||||||
|
* b) Doo^{dag} M_oo^-dag Moo^-1 Doo psi_0 = (D_oo)^dag M_oo^-dag Moo^-1 L^{-1} eta_o
|
||||||
|
* eta_o' = (D_oo)^dag M_oo^-dag Moo^-1 (eta_o - Moe Mee^{-1} eta_e)
|
||||||
|
*
|
||||||
|
* Right precon by Moo^-1
|
||||||
|
* c) M_oo^-dag Doo^{dag} Doo Moo^-1 phi_0 = M_oo^-dag (D_oo)^dag L^{-1} eta_o
|
||||||
|
* eta_o' = M_oo^-dag (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e)
|
||||||
|
* psi_o = M_oo^-1 phi_o
|
||||||
|
* TODO: Deflation
|
||||||
*/
|
*/
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Take a matrix and form a Red Black solver calling a Herm solver
|
||||||
|
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Now make the norm reflect extra factor of Mee
|
||||||
|
template<class Field> class SchurRedBlackStaggeredSolve {
|
||||||
|
private:
|
||||||
|
OperatorFunction<Field> & _HermitianRBSolver;
|
||||||
|
int CBfactorise;
|
||||||
|
public:
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// Wrap the usual normal equations Schur trick
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver) :
|
||||||
|
_HermitianRBSolver(HermitianRBSolver)
|
||||||
|
{
|
||||||
|
CBfactorise=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Matrix>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
||||||
|
ZeroGuesser guess;
|
||||||
|
(*this)(_Matrix,in,out,guess);
|
||||||
|
}
|
||||||
|
template<class Matrix, class Guesser>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out, Guesser &guess){
|
||||||
|
|
||||||
|
// FIXME CGdiagonalMee not implemented virtual function
|
||||||
|
// FIXME use CBfactorise to control schur decomp
|
||||||
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
|
||||||
|
SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
|
||||||
|
Field src_e(grid);
|
||||||
|
Field src_o(grid);
|
||||||
|
Field sol_e(grid);
|
||||||
|
Field sol_o(grid);
|
||||||
|
Field tmp(grid);
|
||||||
|
Field Mtmp(grid);
|
||||||
|
Field resid(fgrid);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << " SchurRedBlackStaggeredSolve " <<std::endl;
|
||||||
|
pickCheckerboard(Even,src_e,in);
|
||||||
|
pickCheckerboard(Odd ,src_o,in);
|
||||||
|
pickCheckerboard(Even,sol_e,out);
|
||||||
|
pickCheckerboard(Odd ,sol_o,out);
|
||||||
|
std::cout << GridLogMessage << " SchurRedBlackStaggeredSolve checkerboards picked" <<std::endl;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// src_o = (source_o - Moe MeeInv source_e)
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
_Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd);
|
||||||
|
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
||||||
|
|
||||||
|
//src_o = tmp; assert(src_o.checkerboard ==Odd);
|
||||||
|
_Matrix.Mooee(tmp,src_o); // Extra factor of "m" in source from dumb choice of matrix norm.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Call the red-black solver
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver calling the Mpc solver" <<std::endl;
|
||||||
|
guess(src_o,sol_o);
|
||||||
|
_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver called the Mpc solver" <<std::endl;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
||||||
|
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver reconstructed other CB" <<std::endl;
|
||||||
|
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver inserted solution" <<std::endl;
|
||||||
|
|
||||||
|
// Verify the unprec residual
|
||||||
|
_Matrix.M(out,resid);
|
||||||
|
resid = resid-in;
|
||||||
|
RealD ns = norm2(in);
|
||||||
|
RealD nr = norm2(resid);
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackStaggered solver true unprec resid "<< std::sqrt(nr/ns) <<" nr "<< nr <<" ns "<<ns << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<class Field> using SchurRedBlackStagSolve = SchurRedBlackStaggeredSolve<Field>;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Take a matrix and form a Red Black solver calling a Herm solver
|
// Take a matrix and form a Red Black solver calling a Herm solver
|
||||||
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
||||||
@ -76,14 +189,17 @@ namespace Grid {
|
|||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
// Wrap the usual normal equations Schur trick
|
// Wrap the usual normal equations Schur trick
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver) :
|
SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver,int cb=0) : _HermitianRBSolver(HermitianRBSolver)
|
||||||
_HermitianRBSolver(HermitianRBSolver)
|
{
|
||||||
{
|
CBfactorise=cb;
|
||||||
CBfactorise=0;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
template<class Matrix>
|
template<class Matrix>
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
||||||
|
ZeroGuesser guess;
|
||||||
|
(*this)(_Matrix,in,out,guess);
|
||||||
|
}
|
||||||
|
template<class Matrix, class Guesser>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
||||||
|
|
||||||
// FIXME CGdiagonalMee not implemented virtual function
|
// FIXME CGdiagonalMee not implemented virtual function
|
||||||
// FIXME use CBfactorise to control schur decomp
|
// FIXME use CBfactorise to control schur decomp
|
||||||
@ -119,6 +235,7 @@ namespace Grid {
|
|||||||
// Call the red-black solver
|
// Call the red-black solver
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
||||||
|
guess(src_o,sol_o);
|
||||||
_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
@ -141,5 +258,178 @@ namespace Grid {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Take a matrix and form a Red Black solver calling a Herm solver
|
||||||
|
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Field> class SchurRedBlackDiagTwoSolve {
|
||||||
|
private:
|
||||||
|
OperatorFunction<Field> & _HermitianRBSolver;
|
||||||
|
int CBfactorise;
|
||||||
|
public:
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// Wrap the usual normal equations Schur trick
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver) :
|
||||||
|
_HermitianRBSolver(HermitianRBSolver)
|
||||||
|
{
|
||||||
|
CBfactorise=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Matrix>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
||||||
|
ZeroGuesser guess;
|
||||||
|
(*this)(_Matrix,in,out,guess);
|
||||||
|
}
|
||||||
|
template<class Matrix,class Guesser>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
||||||
|
|
||||||
|
// FIXME CGdiagonalMee not implemented virtual function
|
||||||
|
// FIXME use CBfactorise to control schur decomp
|
||||||
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
|
||||||
|
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
|
||||||
|
Field src_e(grid);
|
||||||
|
Field src_o(grid);
|
||||||
|
Field sol_e(grid);
|
||||||
|
Field sol_o(grid);
|
||||||
|
Field tmp(grid);
|
||||||
|
Field Mtmp(grid);
|
||||||
|
Field resid(fgrid);
|
||||||
|
|
||||||
|
pickCheckerboard(Even,src_e,in);
|
||||||
|
pickCheckerboard(Odd ,src_o,in);
|
||||||
|
pickCheckerboard(Even,sol_e,out);
|
||||||
|
pickCheckerboard(Odd ,sol_o,out);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// src_o = Mdag * (source_o - Moe MeeInv source_e)
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
_Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd);
|
||||||
|
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
||||||
|
|
||||||
|
// get the right MpcDag
|
||||||
|
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Call the red-black solver
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
||||||
|
// _HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
||||||
|
guess(src_o,tmp);
|
||||||
|
_HermitianRBSolver(_HermOpEO,src_o,tmp); assert(tmp.checkerboard==Odd);
|
||||||
|
_Matrix.MooeeInv(tmp,sol_o); assert( sol_o.checkerboard ==Odd);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
||||||
|
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
|
||||||
|
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
||||||
|
|
||||||
|
// Verify the unprec residual
|
||||||
|
_Matrix.M(out,resid);
|
||||||
|
resid = resid-in;
|
||||||
|
RealD ns = norm2(in);
|
||||||
|
RealD nr = norm2(resid);
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackDiagTwo solver true unprec resid "<< std::sqrt(nr/ns) <<" nr "<< nr <<" ns "<<ns << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Take a matrix and form a Red Black solver calling a Herm solver
|
||||||
|
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Field> class SchurRedBlackDiagTwoMixed {
|
||||||
|
private:
|
||||||
|
LinearFunction<Field> & _HermitianRBSolver;
|
||||||
|
int CBfactorise;
|
||||||
|
public:
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// Wrap the usual normal equations Schur trick
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
SchurRedBlackDiagTwoMixed(LinearFunction<Field> &HermitianRBSolver) :
|
||||||
|
_HermitianRBSolver(HermitianRBSolver)
|
||||||
|
{
|
||||||
|
CBfactorise=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Matrix>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
||||||
|
ZeroGuesser guess;
|
||||||
|
(*this)(_Matrix,in,out,guess);
|
||||||
|
}
|
||||||
|
template<class Matrix, class Guesser>
|
||||||
|
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
||||||
|
|
||||||
|
// FIXME CGdiagonalMee not implemented virtual function
|
||||||
|
// FIXME use CBfactorise to control schur decomp
|
||||||
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
|
||||||
|
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
|
||||||
|
Field src_e(grid);
|
||||||
|
Field src_o(grid);
|
||||||
|
Field sol_e(grid);
|
||||||
|
Field sol_o(grid);
|
||||||
|
Field tmp(grid);
|
||||||
|
Field Mtmp(grid);
|
||||||
|
Field resid(fgrid);
|
||||||
|
|
||||||
|
pickCheckerboard(Even,src_e,in);
|
||||||
|
pickCheckerboard(Odd ,src_o,in);
|
||||||
|
pickCheckerboard(Even,sol_e,out);
|
||||||
|
pickCheckerboard(Odd ,sol_o,out);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// src_o = Mdag * (source_o - Moe MeeInv source_e)
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
_Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd);
|
||||||
|
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
||||||
|
|
||||||
|
// get the right MpcDag
|
||||||
|
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Call the red-black solver
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
||||||
|
// _HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
||||||
|
// _HermitianRBSolver(_HermOpEO,src_o,tmp); assert(tmp.checkerboard==Odd);
|
||||||
|
guess(src_o,tmp);
|
||||||
|
_HermitianRBSolver(src_o,tmp); assert(tmp.checkerboard==Odd);
|
||||||
|
_Matrix.MooeeInv(tmp,sol_o); assert( sol_o.checkerboard ==Odd);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
||||||
|
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
|
||||||
|
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
||||||
|
|
||||||
|
// Verify the unprec residual
|
||||||
|
_Matrix.M(out,resid);
|
||||||
|
resid = resid-in;
|
||||||
|
RealD ns = norm2(in);
|
||||||
|
RealD nr = norm2(resid);
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackDiagTwo solver true unprec resid "<< std::sqrt(nr/ns) <<" nr "<< nr <<" ns "<<ns << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user