mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-15 06:17:05 +01:00
Compare commits
9 Commits
0.8.2
...
feature/ha
Author | SHA1 | Date | |
---|---|---|---|
e307bb7528 | |||
5b8b630919 | |||
81287133f3 | |||
bd27940f78 | |||
d45647698d | |||
d6ac6e75cc | |||
ba34d7b206 | |||
80003787c9 | |||
f523dddef0 |
27
.gitignore
vendored
27
.gitignore
vendored
@ -83,7 +83,6 @@ ltmain.sh
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
.dirstamp
|
||||
|
||||
# build directory #
|
||||
###################
|
||||
@ -98,8 +97,11 @@ build.sh
|
||||
|
||||
# Eigen source #
|
||||
################
|
||||
Grid/Eigen
|
||||
Eigen/*
|
||||
lib/Eigen/*
|
||||
|
||||
# FFTW source #
|
||||
################
|
||||
lib/fftw/*
|
||||
|
||||
# libtool macros #
|
||||
##################
|
||||
@ -110,8 +112,21 @@ m4/libtool.m4
|
||||
################
|
||||
gh-pages/
|
||||
|
||||
# Buck files #
|
||||
##############
|
||||
.buck*
|
||||
buck-out
|
||||
BUCK
|
||||
make-bin-BUCK.sh
|
||||
|
||||
# generated sources #
|
||||
#####################
|
||||
Grid/qcd/spin/gamma-gen/*.h
|
||||
Grid/qcd/spin/gamma-gen/*.cc
|
||||
Grid/util/Version.h
|
||||
lib/qcd/spin/gamma-gen/*.h
|
||||
lib/qcd/spin/gamma-gen/*.cc
|
||||
lib/version.h
|
||||
|
||||
# vs code editor files #
|
||||
########################
|
||||
.vscode/
|
||||
.vscode/settings.json
|
||||
settings.json
|
||||
|
15
.travis.yml
15
.travis.yml
@ -9,11 +9,6 @@ matrix:
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
env: PREC=single
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
env: PREC=double
|
||||
|
||||
before_install:
|
||||
- export GRIDDIR=`pwd`
|
||||
@ -21,7 +16,7 @@ before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export PATH="${GRIDDIR}/clang/bin:${PATH}"; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export LD_LIBRARY_PATH="${GRIDDIR}/clang/lib:${LD_LIBRARY_PATH}"; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc openssl; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc; fi
|
||||
|
||||
install:
|
||||
- export CWD=`pwd`
|
||||
@ -38,7 +33,6 @@ install:
|
||||
- which $CXX
|
||||
- $CXX --version
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export LDFLAGS='-L/usr/local/lib'; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export EXTRACONF='--with-openssl=/usr/local/opt/openssl'; fi
|
||||
|
||||
script:
|
||||
- ./bootstrap.sh
|
||||
@ -55,7 +49,12 @@ script:
|
||||
- make -j4
|
||||
- make install
|
||||
- cd $CWD/build
|
||||
- ../configure --enable-precision=$PREC --enable-simd=SSE4 --enable-comms=none --with-lime=$CWD/build/lime/install ${EXTRACONF}
|
||||
- ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=none --with-lime=$CWD/build/lime/install
|
||||
- make -j4
|
||||
- ./benchmarks/Benchmark_dwf --threads 1 --debug-signals
|
||||
- echo make clean
|
||||
- ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none --with-lime=$CWD/build/lime/install
|
||||
- make -j4
|
||||
- ./benchmarks/Benchmark_dwf --threads 1 --debug-signals
|
||||
- make check
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
Version : 0.8.0
|
||||
|
||||
- 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
|
||||
- Half precision comms
|
||||
|
@ -1,244 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/CommunicationAvoidingGeneralisedMinimalResidual.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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_COMMUNICATION_AVOIDING_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
#define GRID_COMMUNICATION_AVOIDING_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
template<class Field>
|
||||
class CommunicationAvoidingGeneralisedMinimalResidual : public OperatorFunction<Field> {
|
||||
public:
|
||||
bool ErrorOnNoConverge; // Throw an assert when CAGMRES fails to converge,
|
||||
// defaults to true
|
||||
|
||||
RealD Tolerance;
|
||||
|
||||
Integer MaxIterations;
|
||||
Integer RestartLength;
|
||||
Integer MaxNumberOfRestarts;
|
||||
Integer IterationCount; // Number of iterations the CAGMRES took to finish,
|
||||
// filled in upon completion
|
||||
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch QrTimer;
|
||||
GridStopWatch CompSolutionTimer;
|
||||
|
||||
Eigen::MatrixXcd H;
|
||||
|
||||
std::vector<std::complex<double>> y;
|
||||
std::vector<std::complex<double>> gamma;
|
||||
std::vector<std::complex<double>> c;
|
||||
std::vector<std::complex<double>> s;
|
||||
|
||||
CommunicationAvoidingGeneralisedMinimalResidual(RealD tol,
|
||||
Integer maxit,
|
||||
Integer restart_length,
|
||||
bool err_on_no_conv = true)
|
||||
: Tolerance(tol)
|
||||
, MaxIterations(maxit)
|
||||
, RestartLength(restart_length)
|
||||
, MaxNumberOfRestarts(MaxIterations/RestartLength + ((MaxIterations%RestartLength == 0) ? 0 : 1))
|
||||
, ErrorOnNoConverge(err_on_no_conv)
|
||||
, H(Eigen::MatrixXcd::Zero(RestartLength, RestartLength + 1)) // sizes taken from DD-αAMG code base
|
||||
, y(RestartLength + 1, 0.)
|
||||
, gamma(RestartLength + 1, 0.)
|
||||
, c(RestartLength + 1, 0.)
|
||||
, s(RestartLength + 1, 0.) {};
|
||||
|
||||
void operator()(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi) {
|
||||
|
||||
std::cout << GridLogWarning << "This algorithm currently doesn't differ from regular GMRES" << std::endl;
|
||||
|
||||
psi.checkerboard = src.checkerboard;
|
||||
conformable(psi, src);
|
||||
|
||||
RealD guess = norm2(psi);
|
||||
assert(std::isnan(guess) == 0);
|
||||
|
||||
RealD cp;
|
||||
RealD ssq = norm2(src);
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
Field r(src._grid);
|
||||
|
||||
std::cout << std::setprecision(4) << std::scientific;
|
||||
std::cout << GridLogIterative << "CommunicationAvoidingGeneralisedMinimalResidual: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << "CommunicationAvoidingGeneralisedMinimalResidual: src " << ssq << std::endl;
|
||||
|
||||
MatrixTimer.Reset();
|
||||
LinalgTimer.Reset();
|
||||
QrTimer.Reset();
|
||||
CompSolutionTimer.Reset();
|
||||
|
||||
GridStopWatch SolverTimer;
|
||||
SolverTimer.Start();
|
||||
|
||||
IterationCount = 0;
|
||||
|
||||
for (int k=0; k<MaxNumberOfRestarts; k++) {
|
||||
|
||||
cp = outerLoopBody(LinOp, src, psi, rsq);
|
||||
|
||||
// Stopping condition
|
||||
if (cp <= rsq) {
|
||||
|
||||
SolverTimer.Stop();
|
||||
|
||||
LinOp.Op(psi,r);
|
||||
axpy(r,-1.0,src,r);
|
||||
|
||||
RealD srcnorm = sqrt(ssq);
|
||||
RealD resnorm = sqrt(norm2(r));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage << "CommunicationAvoidingGeneralisedMinimalResidual: Converged on iteration " << IterationCount
|
||||
<< " computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual
|
||||
<< " target " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "CAGMRES Time elapsed: Total " << SolverTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "CAGMRES Time elapsed: Matrix " << MatrixTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "CAGMRES Time elapsed: Linalg " << LinalgTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "CAGMRES Time elapsed: QR " << QrTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "CAGMRES Time elapsed: CompSol " << CompSolutionTimer.Elapsed() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "CommunicationAvoidingGeneralisedMinimalResidual did NOT converge" << std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
RealD outerLoopBody(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi, RealD rsq) {
|
||||
|
||||
RealD cp = 0;
|
||||
|
||||
Field w(src._grid);
|
||||
Field r(src._grid);
|
||||
|
||||
// this should probably be made a class member so that it is only allocated once, not in every restart
|
||||
std::vector<Field> v(RestartLength + 1, src._grid); for (auto &elem : v) elem = zero;
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(psi, w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
r = src - w;
|
||||
|
||||
gamma[0] = sqrt(norm2(r));
|
||||
|
||||
v[0] = (1. / gamma[0]) * r;
|
||||
LinalgTimer.Stop();
|
||||
|
||||
for (int i=0; i<RestartLength; i++) {
|
||||
|
||||
IterationCount++;
|
||||
|
||||
arnoldiStep(LinOp, v, w, i);
|
||||
|
||||
qrUpdate(i);
|
||||
|
||||
cp = std::norm(gamma[i+1]);
|
||||
|
||||
std::cout << GridLogIterative << "CommunicationAvoidingGeneralisedMinimalResidual: Iteration " << IterationCount
|
||||
<< " residual " << cp << " target " << rsq << std::endl;
|
||||
|
||||
if ((i == RestartLength - 1) || (IterationCount == MaxIterations) || (cp <= rsq)) {
|
||||
|
||||
computeSolution(v, psi, i);
|
||||
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0); // Never reached
|
||||
return cp;
|
||||
}
|
||||
|
||||
void arnoldiStep(LinearOperatorBase<Field> &LinOp, std::vector<Field> &v, Field &w, int iter) {
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(v[iter], w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
for (int i = 0; i <= iter; ++i) {
|
||||
H(iter, i) = innerProduct(v[i], w);
|
||||
w = w - H(iter, i) * v[i];
|
||||
}
|
||||
|
||||
H(iter, iter + 1) = sqrt(norm2(w));
|
||||
v[iter + 1] = (1. / H(iter, iter + 1)) * w;
|
||||
LinalgTimer.Stop();
|
||||
}
|
||||
|
||||
void qrUpdate(int iter) {
|
||||
|
||||
QrTimer.Start();
|
||||
for (int i = 0; i < iter ; ++i) {
|
||||
auto tmp = -s[i] * H(iter, i) + c[i] * H(iter, i + 1);
|
||||
H(iter, i) = std::conj(c[i]) * H(iter, i) + std::conj(s[i]) * H(iter, i + 1);
|
||||
H(iter, i + 1) = tmp;
|
||||
}
|
||||
|
||||
// Compute new Givens Rotation
|
||||
ComplexD nu = sqrt(std::norm(H(iter, iter)) + std::norm(H(iter, iter + 1)));
|
||||
c[iter] = H(iter, iter) / nu;
|
||||
s[iter] = H(iter, iter + 1) / nu;
|
||||
|
||||
// Apply new Givens rotation
|
||||
H(iter, iter) = nu;
|
||||
H(iter, iter + 1) = 0.;
|
||||
|
||||
gamma[iter + 1] = -s[iter] * gamma[iter];
|
||||
gamma[iter] = std::conj(c[iter]) * gamma[iter];
|
||||
QrTimer.Stop();
|
||||
}
|
||||
|
||||
void computeSolution(std::vector<Field> const &v, Field &psi, int iter) {
|
||||
|
||||
CompSolutionTimer.Start();
|
||||
for (int i = iter; i >= 0; i--) {
|
||||
y[i] = gamma[i];
|
||||
for (int k = i + 1; k <= iter; k++)
|
||||
y[i] = y[i] - H(k, i) * y[k];
|
||||
y[i] = y[i] / H(i, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= iter; i++)
|
||||
psi = psi + v[i] * y[i];
|
||||
CompSolutionTimer.Stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,256 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/FlexibleCommunicationAvoidingGeneralisedMinimalResidual.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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_FLEXIBLE_COMMUNICATION_AVOIDING_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
#define GRID_FLEXIBLE_COMMUNICATION_AVOIDING_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
template<class Field>
|
||||
class FlexibleCommunicationAvoidingGeneralisedMinimalResidual : public OperatorFunction<Field> {
|
||||
public:
|
||||
bool ErrorOnNoConverge; // Throw an assert when FCAGMRES fails to converge,
|
||||
// defaults to true
|
||||
|
||||
RealD Tolerance;
|
||||
|
||||
Integer MaxIterations;
|
||||
Integer RestartLength;
|
||||
Integer MaxNumberOfRestarts;
|
||||
Integer IterationCount; // Number of iterations the FCAGMRES took to finish,
|
||||
// filled in upon completion
|
||||
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch PrecTimer;
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch QrTimer;
|
||||
GridStopWatch CompSolutionTimer;
|
||||
|
||||
Eigen::MatrixXcd H;
|
||||
|
||||
std::vector<std::complex<double>> y;
|
||||
std::vector<std::complex<double>> gamma;
|
||||
std::vector<std::complex<double>> c;
|
||||
std::vector<std::complex<double>> s;
|
||||
|
||||
LinearFunction<Field> &Preconditioner;
|
||||
|
||||
FlexibleCommunicationAvoidingGeneralisedMinimalResidual(RealD tol,
|
||||
Integer maxit,
|
||||
LinearFunction<Field> &Prec,
|
||||
Integer restart_length,
|
||||
bool err_on_no_conv = true)
|
||||
: Tolerance(tol)
|
||||
, MaxIterations(maxit)
|
||||
, RestartLength(restart_length)
|
||||
, MaxNumberOfRestarts(MaxIterations/RestartLength + ((MaxIterations%RestartLength == 0) ? 0 : 1))
|
||||
, ErrorOnNoConverge(err_on_no_conv)
|
||||
, H(Eigen::MatrixXcd::Zero(RestartLength, RestartLength + 1)) // sizes taken from DD-αAMG code base
|
||||
, y(RestartLength + 1, 0.)
|
||||
, gamma(RestartLength + 1, 0.)
|
||||
, c(RestartLength + 1, 0.)
|
||||
, s(RestartLength + 1, 0.)
|
||||
, Preconditioner(Prec) {};
|
||||
|
||||
void operator()(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi) {
|
||||
|
||||
std::cout << GridLogWarning << "This algorithm currently doesn't differ from regular FGMRES" << std::endl;
|
||||
|
||||
psi.checkerboard = src.checkerboard;
|
||||
conformable(psi, src);
|
||||
|
||||
RealD guess = norm2(psi);
|
||||
assert(std::isnan(guess) == 0);
|
||||
|
||||
RealD cp;
|
||||
RealD ssq = norm2(src);
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
Field r(src._grid);
|
||||
|
||||
std::cout << std::setprecision(4) << std::scientific;
|
||||
std::cout << GridLogIterative << "FlexibleCommunicationAvoidingGeneralisedMinimalResidual: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << "FlexibleCommunicationAvoidingGeneralisedMinimalResidual: src " << ssq << std::endl;
|
||||
|
||||
PrecTimer.Reset();
|
||||
MatrixTimer.Reset();
|
||||
LinalgTimer.Reset();
|
||||
QrTimer.Reset();
|
||||
CompSolutionTimer.Reset();
|
||||
|
||||
GridStopWatch SolverTimer;
|
||||
SolverTimer.Start();
|
||||
|
||||
IterationCount = 0;
|
||||
|
||||
for (int k=0; k<MaxNumberOfRestarts; k++) {
|
||||
|
||||
cp = outerLoopBody(LinOp, src, psi, rsq);
|
||||
|
||||
// Stopping condition
|
||||
if (cp <= rsq) {
|
||||
|
||||
SolverTimer.Stop();
|
||||
|
||||
LinOp.Op(psi,r);
|
||||
axpy(r,-1.0,src,r);
|
||||
|
||||
RealD srcnorm = sqrt(ssq);
|
||||
RealD resnorm = sqrt(norm2(r));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage << "FlexibleCommunicationAvoidingGeneralisedMinimalResidual: Converged on iteration " << IterationCount
|
||||
<< " computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual
|
||||
<< " target " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "FCAGMRES Time elapsed: Total " << SolverTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FCAGMRES Time elapsed: Precon " << PrecTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FCAGMRES Time elapsed: Matrix " << MatrixTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FCAGMRES Time elapsed: Linalg " << LinalgTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FCAGMRES Time elapsed: QR " << QrTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FCAGMRES Time elapsed: CompSol " << CompSolutionTimer.Elapsed() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "FlexibleCommunicationAvoidingGeneralisedMinimalResidual did NOT converge" << std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
RealD outerLoopBody(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi, RealD rsq) {
|
||||
|
||||
RealD cp = 0;
|
||||
|
||||
Field w(src._grid);
|
||||
Field r(src._grid);
|
||||
|
||||
// these should probably be made class members so that they are only allocated once, not in every restart
|
||||
std::vector<Field> v(RestartLength + 1, src._grid); for (auto &elem : v) elem = zero;
|
||||
std::vector<Field> z(RestartLength + 1, src._grid); for (auto &elem : z) elem = zero;
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(psi, w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
r = src - w;
|
||||
|
||||
gamma[0] = sqrt(norm2(r));
|
||||
|
||||
v[0] = (1. / gamma[0]) * r;
|
||||
LinalgTimer.Stop();
|
||||
|
||||
for (int i=0; i<RestartLength; i++) {
|
||||
|
||||
IterationCount++;
|
||||
|
||||
arnoldiStep(LinOp, v, z, w, i);
|
||||
|
||||
qrUpdate(i);
|
||||
|
||||
cp = std::norm(gamma[i+1]);
|
||||
|
||||
std::cout << GridLogIterative << "FlexibleCommunicationAvoidingGeneralisedMinimalResidual: Iteration " << IterationCount
|
||||
<< " residual " << cp << " target " << rsq << std::endl;
|
||||
|
||||
if ((i == RestartLength - 1) || (IterationCount == MaxIterations) || (cp <= rsq)) {
|
||||
|
||||
computeSolution(z, psi, i);
|
||||
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0); // Never reached
|
||||
return cp;
|
||||
}
|
||||
|
||||
void arnoldiStep(LinearOperatorBase<Field> &LinOp, std::vector<Field> &v, std::vector<Field> &z, Field &w, int iter) {
|
||||
|
||||
PrecTimer.Start();
|
||||
Preconditioner(v[iter], z[iter]);
|
||||
PrecTimer.Stop();
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(z[iter], w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
for (int i = 0; i <= iter; ++i) {
|
||||
H(iter, i) = innerProduct(v[i], w);
|
||||
w = w - H(iter, i) * v[i];
|
||||
}
|
||||
|
||||
H(iter, iter + 1) = sqrt(norm2(w));
|
||||
v[iter + 1] = (1. / H(iter, iter + 1)) * w;
|
||||
LinalgTimer.Stop();
|
||||
}
|
||||
|
||||
void qrUpdate(int iter) {
|
||||
|
||||
QrTimer.Start();
|
||||
for (int i = 0; i < iter ; ++i) {
|
||||
auto tmp = -s[i] * H(iter, i) + c[i] * H(iter, i + 1);
|
||||
H(iter, i) = std::conj(c[i]) * H(iter, i) + std::conj(s[i]) * H(iter, i + 1);
|
||||
H(iter, i + 1) = tmp;
|
||||
}
|
||||
|
||||
// Compute new Givens Rotation
|
||||
ComplexD nu = sqrt(std::norm(H(iter, iter)) + std::norm(H(iter, iter + 1)));
|
||||
c[iter] = H(iter, iter) / nu;
|
||||
s[iter] = H(iter, iter + 1) / nu;
|
||||
|
||||
// Apply new Givens rotation
|
||||
H(iter, iter) = nu;
|
||||
H(iter, iter + 1) = 0.;
|
||||
|
||||
gamma[iter + 1] = -s[iter] * gamma[iter];
|
||||
gamma[iter] = std::conj(c[iter]) * gamma[iter];
|
||||
QrTimer.Stop();
|
||||
}
|
||||
|
||||
void computeSolution(std::vector<Field> const &z, Field &psi, int iter) {
|
||||
|
||||
CompSolutionTimer.Start();
|
||||
for (int i = iter; i >= 0; i--) {
|
||||
y[i] = gamma[i];
|
||||
for (int k = i + 1; k <= iter; k++)
|
||||
y[i] = y[i] - H(k, i) * y[k];
|
||||
y[i] = y[i] / H(i, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= iter; i++)
|
||||
psi = psi + z[i] * y[i];
|
||||
CompSolutionTimer.Stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,254 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/FlexibleGeneralisedMinimalResidual.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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_FLEXIBLE_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
#define GRID_FLEXIBLE_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
template<class Field>
|
||||
class FlexibleGeneralisedMinimalResidual : public OperatorFunction<Field> {
|
||||
public:
|
||||
bool ErrorOnNoConverge; // Throw an assert when FGMRES fails to converge,
|
||||
// defaults to true
|
||||
|
||||
RealD Tolerance;
|
||||
|
||||
Integer MaxIterations;
|
||||
Integer RestartLength;
|
||||
Integer MaxNumberOfRestarts;
|
||||
Integer IterationCount; // Number of iterations the FGMRES took to finish,
|
||||
// filled in upon completion
|
||||
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch PrecTimer;
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch QrTimer;
|
||||
GridStopWatch CompSolutionTimer;
|
||||
|
||||
Eigen::MatrixXcd H;
|
||||
|
||||
std::vector<std::complex<double>> y;
|
||||
std::vector<std::complex<double>> gamma;
|
||||
std::vector<std::complex<double>> c;
|
||||
std::vector<std::complex<double>> s;
|
||||
|
||||
LinearFunction<Field> &Preconditioner;
|
||||
|
||||
FlexibleGeneralisedMinimalResidual(RealD tol,
|
||||
Integer maxit,
|
||||
LinearFunction<Field> &Prec,
|
||||
Integer restart_length,
|
||||
bool err_on_no_conv = true)
|
||||
: Tolerance(tol)
|
||||
, MaxIterations(maxit)
|
||||
, RestartLength(restart_length)
|
||||
, MaxNumberOfRestarts(MaxIterations/RestartLength + ((MaxIterations%RestartLength == 0) ? 0 : 1))
|
||||
, ErrorOnNoConverge(err_on_no_conv)
|
||||
, H(Eigen::MatrixXcd::Zero(RestartLength, RestartLength + 1)) // sizes taken from DD-αAMG code base
|
||||
, y(RestartLength + 1, 0.)
|
||||
, gamma(RestartLength + 1, 0.)
|
||||
, c(RestartLength + 1, 0.)
|
||||
, s(RestartLength + 1, 0.)
|
||||
, Preconditioner(Prec) {};
|
||||
|
||||
void operator()(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi) {
|
||||
|
||||
psi.checkerboard = src.checkerboard;
|
||||
conformable(psi, src);
|
||||
|
||||
RealD guess = norm2(psi);
|
||||
assert(std::isnan(guess) == 0);
|
||||
|
||||
RealD cp;
|
||||
RealD ssq = norm2(src);
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
Field r(src._grid);
|
||||
|
||||
std::cout << std::setprecision(4) << std::scientific;
|
||||
std::cout << GridLogIterative << "FlexibleGeneralisedMinimalResidual: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << "FlexibleGeneralisedMinimalResidual: src " << ssq << std::endl;
|
||||
|
||||
PrecTimer.Reset();
|
||||
MatrixTimer.Reset();
|
||||
LinalgTimer.Reset();
|
||||
QrTimer.Reset();
|
||||
CompSolutionTimer.Reset();
|
||||
|
||||
GridStopWatch SolverTimer;
|
||||
SolverTimer.Start();
|
||||
|
||||
IterationCount = 0;
|
||||
|
||||
for (int k=0; k<MaxNumberOfRestarts; k++) {
|
||||
|
||||
cp = outerLoopBody(LinOp, src, psi, rsq);
|
||||
|
||||
// Stopping condition
|
||||
if (cp <= rsq) {
|
||||
|
||||
SolverTimer.Stop();
|
||||
|
||||
LinOp.Op(psi,r);
|
||||
axpy(r,-1.0,src,r);
|
||||
|
||||
RealD srcnorm = sqrt(ssq);
|
||||
RealD resnorm = sqrt(norm2(r));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage << "FlexibleGeneralisedMinimalResidual: Converged on iteration " << IterationCount
|
||||
<< " computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual
|
||||
<< " target " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "FGMRES Time elapsed: Total " << SolverTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FGMRES Time elapsed: Precon " << PrecTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FGMRES Time elapsed: Matrix " << MatrixTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FGMRES Time elapsed: Linalg " << LinalgTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FGMRES Time elapsed: QR " << QrTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "FGMRES Time elapsed: CompSol " << CompSolutionTimer.Elapsed() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "FlexibleGeneralisedMinimalResidual did NOT converge" << std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
RealD outerLoopBody(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi, RealD rsq) {
|
||||
|
||||
RealD cp = 0;
|
||||
|
||||
Field w(src._grid);
|
||||
Field r(src._grid);
|
||||
|
||||
// these should probably be made class members so that they are only allocated once, not in every restart
|
||||
std::vector<Field> v(RestartLength + 1, src._grid); for (auto &elem : v) elem = zero;
|
||||
std::vector<Field> z(RestartLength + 1, src._grid); for (auto &elem : z) elem = zero;
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(psi, w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
r = src - w;
|
||||
|
||||
gamma[0] = sqrt(norm2(r));
|
||||
|
||||
v[0] = (1. / gamma[0]) * r;
|
||||
LinalgTimer.Stop();
|
||||
|
||||
for (int i=0; i<RestartLength; i++) {
|
||||
|
||||
IterationCount++;
|
||||
|
||||
arnoldiStep(LinOp, v, z, w, i);
|
||||
|
||||
qrUpdate(i);
|
||||
|
||||
cp = std::norm(gamma[i+1]);
|
||||
|
||||
std::cout << GridLogIterative << "FlexibleGeneralisedMinimalResidual: Iteration " << IterationCount
|
||||
<< " residual " << cp << " target " << rsq << std::endl;
|
||||
|
||||
if ((i == RestartLength - 1) || (IterationCount == MaxIterations) || (cp <= rsq)) {
|
||||
|
||||
computeSolution(z, psi, i);
|
||||
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0); // Never reached
|
||||
return cp;
|
||||
}
|
||||
|
||||
void arnoldiStep(LinearOperatorBase<Field> &LinOp, std::vector<Field> &v, std::vector<Field> &z, Field &w, int iter) {
|
||||
|
||||
PrecTimer.Start();
|
||||
Preconditioner(v[iter], z[iter]);
|
||||
PrecTimer.Stop();
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(z[iter], w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
for (int i = 0; i <= iter; ++i) {
|
||||
H(iter, i) = innerProduct(v[i], w);
|
||||
w = w - H(iter, i) * v[i];
|
||||
}
|
||||
|
||||
H(iter, iter + 1) = sqrt(norm2(w));
|
||||
v[iter + 1] = (1. / H(iter, iter + 1)) * w;
|
||||
LinalgTimer.Stop();
|
||||
}
|
||||
|
||||
void qrUpdate(int iter) {
|
||||
|
||||
QrTimer.Start();
|
||||
for (int i = 0; i < iter ; ++i) {
|
||||
auto tmp = -s[i] * H(iter, i) + c[i] * H(iter, i + 1);
|
||||
H(iter, i) = std::conj(c[i]) * H(iter, i) + std::conj(s[i]) * H(iter, i + 1);
|
||||
H(iter, i + 1) = tmp;
|
||||
}
|
||||
|
||||
// Compute new Givens Rotation
|
||||
ComplexD nu = sqrt(std::norm(H(iter, iter)) + std::norm(H(iter, iter + 1)));
|
||||
c[iter] = H(iter, iter) / nu;
|
||||
s[iter] = H(iter, iter + 1) / nu;
|
||||
|
||||
// Apply new Givens rotation
|
||||
H(iter, iter) = nu;
|
||||
H(iter, iter + 1) = 0.;
|
||||
|
||||
gamma[iter + 1] = -s[iter] * gamma[iter];
|
||||
gamma[iter] = std::conj(c[iter]) * gamma[iter];
|
||||
QrTimer.Stop();
|
||||
}
|
||||
|
||||
void computeSolution(std::vector<Field> const &z, Field &psi, int iter) {
|
||||
|
||||
CompSolutionTimer.Start();
|
||||
for (int i = iter; i >= 0; i--) {
|
||||
y[i] = gamma[i];
|
||||
for (int k = i + 1; k <= iter; k++)
|
||||
y[i] = y[i] - H(k, i) * y[k];
|
||||
y[i] = y[i] / H(i, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= iter; i++)
|
||||
psi = psi + z[i] * y[i];
|
||||
CompSolutionTimer.Stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,242 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/GeneralisedMinimalResidual.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
#define GRID_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
template<class Field>
|
||||
class GeneralisedMinimalResidual : public OperatorFunction<Field> {
|
||||
public:
|
||||
bool ErrorOnNoConverge; // Throw an assert when GMRES fails to converge,
|
||||
// defaults to true
|
||||
|
||||
RealD Tolerance;
|
||||
|
||||
Integer MaxIterations;
|
||||
Integer RestartLength;
|
||||
Integer MaxNumberOfRestarts;
|
||||
Integer IterationCount; // Number of iterations the GMRES took to finish,
|
||||
// filled in upon completion
|
||||
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch QrTimer;
|
||||
GridStopWatch CompSolutionTimer;
|
||||
|
||||
Eigen::MatrixXcd H;
|
||||
|
||||
std::vector<std::complex<double>> y;
|
||||
std::vector<std::complex<double>> gamma;
|
||||
std::vector<std::complex<double>> c;
|
||||
std::vector<std::complex<double>> s;
|
||||
|
||||
GeneralisedMinimalResidual(RealD tol,
|
||||
Integer maxit,
|
||||
Integer restart_length,
|
||||
bool err_on_no_conv = true)
|
||||
: Tolerance(tol)
|
||||
, MaxIterations(maxit)
|
||||
, RestartLength(restart_length)
|
||||
, MaxNumberOfRestarts(MaxIterations/RestartLength + ((MaxIterations%RestartLength == 0) ? 0 : 1))
|
||||
, ErrorOnNoConverge(err_on_no_conv)
|
||||
, H(Eigen::MatrixXcd::Zero(RestartLength, RestartLength + 1)) // sizes taken from DD-αAMG code base
|
||||
, y(RestartLength + 1, 0.)
|
||||
, gamma(RestartLength + 1, 0.)
|
||||
, c(RestartLength + 1, 0.)
|
||||
, s(RestartLength + 1, 0.) {};
|
||||
|
||||
void operator()(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi) {
|
||||
|
||||
psi.checkerboard = src.checkerboard;
|
||||
conformable(psi, src);
|
||||
|
||||
RealD guess = norm2(psi);
|
||||
assert(std::isnan(guess) == 0);
|
||||
|
||||
RealD cp;
|
||||
RealD ssq = norm2(src);
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
Field r(src._grid);
|
||||
|
||||
std::cout << std::setprecision(4) << std::scientific;
|
||||
std::cout << GridLogIterative << "GeneralisedMinimalResidual: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << "GeneralisedMinimalResidual: src " << ssq << std::endl;
|
||||
|
||||
MatrixTimer.Reset();
|
||||
LinalgTimer.Reset();
|
||||
QrTimer.Reset();
|
||||
CompSolutionTimer.Reset();
|
||||
|
||||
GridStopWatch SolverTimer;
|
||||
SolverTimer.Start();
|
||||
|
||||
IterationCount = 0;
|
||||
|
||||
for (int k=0; k<MaxNumberOfRestarts; k++) {
|
||||
|
||||
cp = outerLoopBody(LinOp, src, psi, rsq);
|
||||
|
||||
// Stopping condition
|
||||
if (cp <= rsq) {
|
||||
|
||||
SolverTimer.Stop();
|
||||
|
||||
LinOp.Op(psi,r);
|
||||
axpy(r,-1.0,src,r);
|
||||
|
||||
RealD srcnorm = sqrt(ssq);
|
||||
RealD resnorm = sqrt(norm2(r));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage << "GeneralisedMinimalResidual: Converged on iteration " << IterationCount
|
||||
<< " computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual
|
||||
<< " target " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "GMRES Time elapsed: Total " << SolverTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "GMRES Time elapsed: Matrix " << MatrixTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "GMRES Time elapsed: Linalg " << LinalgTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "GMRES Time elapsed: QR " << QrTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "GMRES Time elapsed: CompSol " << CompSolutionTimer.Elapsed() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "GeneralisedMinimalResidual did NOT converge" << std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
RealD outerLoopBody(LinearOperatorBase<Field> &LinOp, const Field &src, Field &psi, RealD rsq) {
|
||||
|
||||
RealD cp = 0;
|
||||
|
||||
Field w(src._grid);
|
||||
Field r(src._grid);
|
||||
|
||||
// this should probably be made a class member so that it is only allocated once, not in every restart
|
||||
std::vector<Field> v(RestartLength + 1, src._grid); for (auto &elem : v) elem = zero;
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(psi, w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
r = src - w;
|
||||
|
||||
gamma[0] = sqrt(norm2(r));
|
||||
|
||||
v[0] = (1. / gamma[0]) * r;
|
||||
LinalgTimer.Stop();
|
||||
|
||||
for (int i=0; i<RestartLength; i++) {
|
||||
|
||||
IterationCount++;
|
||||
|
||||
arnoldiStep(LinOp, v, w, i);
|
||||
|
||||
qrUpdate(i);
|
||||
|
||||
cp = std::norm(gamma[i+1]);
|
||||
|
||||
std::cout << GridLogIterative << "GeneralisedMinimalResidual: Iteration " << IterationCount
|
||||
<< " residual " << cp << " target " << rsq << std::endl;
|
||||
|
||||
if ((i == RestartLength - 1) || (IterationCount == MaxIterations) || (cp <= rsq)) {
|
||||
|
||||
computeSolution(v, psi, i);
|
||||
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0); // Never reached
|
||||
return cp;
|
||||
}
|
||||
|
||||
void arnoldiStep(LinearOperatorBase<Field> &LinOp, std::vector<Field> &v, Field &w, int iter) {
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(v[iter], w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
for (int i = 0; i <= iter; ++i) {
|
||||
H(iter, i) = innerProduct(v[i], w);
|
||||
w = w - H(iter, i) * v[i];
|
||||
}
|
||||
|
||||
H(iter, iter + 1) = sqrt(norm2(w));
|
||||
v[iter + 1] = (1. / H(iter, iter + 1)) * w;
|
||||
LinalgTimer.Stop();
|
||||
}
|
||||
|
||||
void qrUpdate(int iter) {
|
||||
|
||||
QrTimer.Start();
|
||||
for (int i = 0; i < iter ; ++i) {
|
||||
auto tmp = -s[i] * H(iter, i) + c[i] * H(iter, i + 1);
|
||||
H(iter, i) = std::conj(c[i]) * H(iter, i) + std::conj(s[i]) * H(iter, i + 1);
|
||||
H(iter, i + 1) = tmp;
|
||||
}
|
||||
|
||||
// Compute new Givens Rotation
|
||||
ComplexD nu = sqrt(std::norm(H(iter, iter)) + std::norm(H(iter, iter + 1)));
|
||||
c[iter] = H(iter, iter) / nu;
|
||||
s[iter] = H(iter, iter + 1) / nu;
|
||||
|
||||
// Apply new Givens rotation
|
||||
H(iter, iter) = nu;
|
||||
H(iter, iter + 1) = 0.;
|
||||
|
||||
gamma[iter + 1] = -s[iter] * gamma[iter];
|
||||
gamma[iter] = std::conj(c[iter]) * gamma[iter];
|
||||
QrTimer.Stop();
|
||||
}
|
||||
|
||||
void computeSolution(std::vector<Field> const &v, Field &psi, int iter) {
|
||||
|
||||
CompSolutionTimer.Start();
|
||||
for (int i = iter; i >= 0; i--) {
|
||||
y[i] = gamma[i];
|
||||
for (int k = i + 1; k <= iter; k++)
|
||||
y[i] = y[i] - H(k, i) * y[k];
|
||||
y[i] = y[i] / H(i, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= iter; i++)
|
||||
psi = psi + v[i] * y[i];
|
||||
CompSolutionTimer.Stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,156 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/MinimalResidual.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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_MINIMAL_RESIDUAL_H
|
||||
#define GRID_MINIMAL_RESIDUAL_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
template<class Field> class MinimalResidual : public OperatorFunction<Field> {
|
||||
public:
|
||||
bool ErrorOnNoConverge; // throw an assert when the MR fails to converge.
|
||||
// Defaults true.
|
||||
RealD Tolerance;
|
||||
Integer MaxIterations;
|
||||
RealD overRelaxParam;
|
||||
Integer IterationsToComplete; // Number of iterations the MR took to finish.
|
||||
// Filled in upon completion
|
||||
|
||||
MinimalResidual(RealD tol, Integer maxit, Real ovrelparam = 1.0, bool err_on_no_conv = true)
|
||||
: Tolerance(tol), MaxIterations(maxit), overRelaxParam(ovrelparam), ErrorOnNoConverge(err_on_no_conv){};
|
||||
|
||||
void operator()(LinearOperatorBase<Field> &Linop, const Field &src, Field &psi) {
|
||||
|
||||
psi.checkerboard = src.checkerboard;
|
||||
conformable(psi, src);
|
||||
|
||||
Complex a, c;
|
||||
Real d;
|
||||
|
||||
Field Mr(src);
|
||||
Field r(src);
|
||||
|
||||
// Initial residual computation & set up
|
||||
RealD guess = norm2(psi);
|
||||
assert(std::isnan(guess) == 0);
|
||||
|
||||
RealD ssq = norm2(src);
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
Linop.Op(psi, Mr);
|
||||
|
||||
r = src - Mr;
|
||||
|
||||
RealD cp = norm2(r);
|
||||
|
||||
std::cout << std::setprecision(4) << std::scientific;
|
||||
std::cout << GridLogIterative << "MinimalResidual: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << "MinimalResidual: src " << ssq << std::endl;
|
||||
std::cout << GridLogIterative << "MinimalResidual: mp " << d << std::endl;
|
||||
std::cout << GridLogIterative << "MinimalResidual: cp,r " << cp << std::endl;
|
||||
|
||||
if (cp <= rsq) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << GridLogIterative << "MinimalResidual: k=0 residual " << cp << " target " << rsq << std::endl;
|
||||
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch SolverTimer;
|
||||
|
||||
SolverTimer.Start();
|
||||
int k;
|
||||
for (k = 1; k <= MaxIterations; k++) {
|
||||
|
||||
MatrixTimer.Start();
|
||||
Linop.Op(r, Mr);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
|
||||
c = innerProduct(Mr, r);
|
||||
|
||||
d = norm2(Mr);
|
||||
|
||||
a = c / d;
|
||||
|
||||
a = a * overRelaxParam;
|
||||
|
||||
psi = psi + r * a;
|
||||
|
||||
r = r - Mr * a;
|
||||
|
||||
cp = norm2(r);
|
||||
|
||||
LinalgTimer.Stop();
|
||||
|
||||
std::cout << GridLogIterative << "MinimalResidual: Iteration " << k
|
||||
<< " residual " << cp << " target " << rsq << std::endl;
|
||||
std::cout << GridLogDebug << "a = " << a << " c = " << c << " d = " << d << std::endl;
|
||||
|
||||
// Stopping condition
|
||||
if (cp <= rsq) {
|
||||
SolverTimer.Stop();
|
||||
|
||||
Linop.Op(psi, Mr);
|
||||
r = src - Mr;
|
||||
|
||||
RealD srcnorm = sqrt(ssq);
|
||||
RealD resnorm = sqrt(norm2(r));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage << "MinimalResidual Converged on iteration " << k
|
||||
<< " computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual
|
||||
<< " target " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "MR Time elapsed: Total " << SolverTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MR Time elapsed: Matrix " << MatrixTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MR Time elapsed: Linalg " << LinalgTimer.Elapsed() << std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(true_residual / Tolerance < 10000.0);
|
||||
|
||||
IterationsToComplete = k;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "MinimalResidual did NOT converge"
|
||||
<< std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(0);
|
||||
|
||||
IterationsToComplete = k;
|
||||
}
|
||||
};
|
||||
} // namespace Grid
|
||||
#endif
|
@ -1,273 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/MixedPrecisionFlexibleGeneralisedMinimalResidual.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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_MIXED_PRECISION_FLEXIBLE_GENERALISED_MINIMAL_RESIDUAL_H
|
||||
#define GRID_MIXED_PRECISION_FLEXIBLE_GENERALISED_MINIMAL_RESIDUAL_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 MixedPrecisionFlexibleGeneralisedMinimalResidual : public OperatorFunction<FieldD> {
|
||||
public:
|
||||
bool ErrorOnNoConverge; // Throw an assert when MPFGMRES fails to converge,
|
||||
// defaults to true
|
||||
|
||||
RealD Tolerance;
|
||||
|
||||
Integer MaxIterations;
|
||||
Integer RestartLength;
|
||||
Integer MaxNumberOfRestarts;
|
||||
Integer IterationCount; // Number of iterations the MPFGMRES took to finish,
|
||||
// filled in upon completion
|
||||
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch PrecTimer;
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch QrTimer;
|
||||
GridStopWatch CompSolutionTimer;
|
||||
GridStopWatch ChangePrecTimer;
|
||||
|
||||
Eigen::MatrixXcd H;
|
||||
|
||||
std::vector<std::complex<double>> y;
|
||||
std::vector<std::complex<double>> gamma;
|
||||
std::vector<std::complex<double>> c;
|
||||
std::vector<std::complex<double>> s;
|
||||
|
||||
GridBase* SinglePrecGrid;
|
||||
|
||||
LinearFunction<FieldF> &Preconditioner;
|
||||
|
||||
MixedPrecisionFlexibleGeneralisedMinimalResidual(RealD tol,
|
||||
Integer maxit,
|
||||
GridBase * sp_grid,
|
||||
LinearFunction<FieldF> &Prec,
|
||||
Integer restart_length,
|
||||
bool err_on_no_conv = true)
|
||||
: Tolerance(tol)
|
||||
, MaxIterations(maxit)
|
||||
, RestartLength(restart_length)
|
||||
, MaxNumberOfRestarts(MaxIterations/RestartLength + ((MaxIterations%RestartLength == 0) ? 0 : 1))
|
||||
, ErrorOnNoConverge(err_on_no_conv)
|
||||
, H(Eigen::MatrixXcd::Zero(RestartLength, RestartLength + 1)) // sizes taken from DD-αAMG code base
|
||||
, y(RestartLength + 1, 0.)
|
||||
, gamma(RestartLength + 1, 0.)
|
||||
, c(RestartLength + 1, 0.)
|
||||
, s(RestartLength + 1, 0.)
|
||||
, SinglePrecGrid(sp_grid)
|
||||
, Preconditioner(Prec) {};
|
||||
|
||||
void operator()(LinearOperatorBase<FieldD> &LinOp, const FieldD &src, FieldD &psi) {
|
||||
|
||||
psi.checkerboard = src.checkerboard;
|
||||
conformable(psi, src);
|
||||
|
||||
RealD guess = norm2(psi);
|
||||
assert(std::isnan(guess) == 0);
|
||||
|
||||
RealD cp;
|
||||
RealD ssq = norm2(src);
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
FieldD r(src._grid);
|
||||
|
||||
std::cout << std::setprecision(4) << std::scientific;
|
||||
std::cout << GridLogIterative << "MPFGMRES: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << "MPFGMRES: src " << ssq << std::endl;
|
||||
|
||||
PrecTimer.Reset();
|
||||
MatrixTimer.Reset();
|
||||
LinalgTimer.Reset();
|
||||
QrTimer.Reset();
|
||||
CompSolutionTimer.Reset();
|
||||
ChangePrecTimer.Reset();
|
||||
|
||||
GridStopWatch SolverTimer;
|
||||
SolverTimer.Start();
|
||||
|
||||
IterationCount = 0;
|
||||
|
||||
for (int k=0; k<MaxNumberOfRestarts; k++) {
|
||||
|
||||
cp = outerLoopBody(LinOp, src, psi, rsq);
|
||||
|
||||
// Stopping condition
|
||||
if (cp <= rsq) {
|
||||
|
||||
SolverTimer.Stop();
|
||||
|
||||
LinOp.Op(psi,r);
|
||||
axpy(r,-1.0,src,r);
|
||||
|
||||
RealD srcnorm = sqrt(ssq);
|
||||
RealD resnorm = sqrt(norm2(r));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage << "MPFGMRES: Converged on iteration " << IterationCount
|
||||
<< " computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual
|
||||
<< " target " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: Total " << SolverTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: Precon " << PrecTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: Matrix " << MatrixTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: Linalg " << LinalgTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: QR " << QrTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: CompSol " << CompSolutionTimer.Elapsed() << std::endl;
|
||||
std::cout << GridLogMessage << "MPFGMRES Time elapsed: PrecChange " << ChangePrecTimer.Elapsed() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "MPFGMRES did NOT converge" << std::endl;
|
||||
|
||||
if (ErrorOnNoConverge)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
RealD outerLoopBody(LinearOperatorBase<FieldD> &LinOp, const FieldD &src, FieldD &psi, RealD rsq) {
|
||||
|
||||
RealD cp = 0;
|
||||
|
||||
FieldD w(src._grid);
|
||||
FieldD r(src._grid);
|
||||
|
||||
// these should probably be made class members so that they are only allocated once, not in every restart
|
||||
std::vector<FieldD> v(RestartLength + 1, src._grid); for (auto &elem : v) elem = zero;
|
||||
std::vector<FieldD> z(RestartLength + 1, src._grid); for (auto &elem : z) elem = zero;
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(psi, w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
r = src - w;
|
||||
|
||||
gamma[0] = sqrt(norm2(r));
|
||||
|
||||
v[0] = (1. / gamma[0]) * r;
|
||||
LinalgTimer.Stop();
|
||||
|
||||
for (int i=0; i<RestartLength; i++) {
|
||||
|
||||
IterationCount++;
|
||||
|
||||
arnoldiStep(LinOp, v, z, w, i);
|
||||
|
||||
qrUpdate(i);
|
||||
|
||||
cp = std::norm(gamma[i+1]);
|
||||
|
||||
std::cout << GridLogIterative << "MPFGMRES: Iteration " << IterationCount
|
||||
<< " residual " << cp << " target " << rsq << std::endl;
|
||||
|
||||
if ((i == RestartLength - 1) || (IterationCount == MaxIterations) || (cp <= rsq)) {
|
||||
|
||||
computeSolution(z, psi, i);
|
||||
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0); // Never reached
|
||||
return cp;
|
||||
}
|
||||
|
||||
void arnoldiStep(LinearOperatorBase<FieldD> &LinOp, std::vector<FieldD> &v, std::vector<FieldD> &z, FieldD &w, int iter) {
|
||||
|
||||
FieldF v_f(SinglePrecGrid);
|
||||
FieldF z_f(SinglePrecGrid);
|
||||
|
||||
ChangePrecTimer.Start();
|
||||
precisionChange(v_f, v[iter]);
|
||||
precisionChange(z_f, z[iter]);
|
||||
ChangePrecTimer.Stop();
|
||||
|
||||
PrecTimer.Start();
|
||||
Preconditioner(v_f, z_f);
|
||||
PrecTimer.Stop();
|
||||
|
||||
ChangePrecTimer.Start();
|
||||
precisionChange(z[iter], z_f);
|
||||
ChangePrecTimer.Stop();
|
||||
|
||||
MatrixTimer.Start();
|
||||
LinOp.Op(z[iter], w);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
LinalgTimer.Start();
|
||||
for (int i = 0; i <= iter; ++i) {
|
||||
H(iter, i) = innerProduct(v[i], w);
|
||||
w = w - H(iter, i) * v[i];
|
||||
}
|
||||
|
||||
H(iter, iter + 1) = sqrt(norm2(w));
|
||||
v[iter + 1] = (1. / H(iter, iter + 1)) * w;
|
||||
LinalgTimer.Stop();
|
||||
}
|
||||
|
||||
void qrUpdate(int iter) {
|
||||
|
||||
QrTimer.Start();
|
||||
for (int i = 0; i < iter ; ++i) {
|
||||
auto tmp = -s[i] * H(iter, i) + c[i] * H(iter, i + 1);
|
||||
H(iter, i) = std::conj(c[i]) * H(iter, i) + std::conj(s[i]) * H(iter, i + 1);
|
||||
H(iter, i + 1) = tmp;
|
||||
}
|
||||
|
||||
// Compute new Givens Rotation
|
||||
ComplexD nu = sqrt(std::norm(H(iter, iter)) + std::norm(H(iter, iter + 1)));
|
||||
c[iter] = H(iter, iter) / nu;
|
||||
s[iter] = H(iter, iter + 1) / nu;
|
||||
|
||||
// Apply new Givens rotation
|
||||
H(iter, iter) = nu;
|
||||
H(iter, iter + 1) = 0.;
|
||||
|
||||
gamma[iter + 1] = -s[iter] * gamma[iter];
|
||||
gamma[iter] = std::conj(c[iter]) * gamma[iter];
|
||||
QrTimer.Stop();
|
||||
}
|
||||
|
||||
void computeSolution(std::vector<FieldD> const &z, FieldD &psi, int iter) {
|
||||
|
||||
CompSolutionTimer.Start();
|
||||
for (int i = iter; i >= 0; i--) {
|
||||
y[i] = gamma[i];
|
||||
for (int k = i + 1; k <= iter; k++)
|
||||
y[i] = y[i] - H(k, i) * y[k];
|
||||
y[i] = y[i] / H(i, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= iter; i++)
|
||||
psi = psi + z[i] * y[i];
|
||||
CompSolutionTimer.Stop();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
namespace Grid {
|
||||
template<class Field> class PowerMethod
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename T> static RealD normalise(T& v)
|
||||
{
|
||||
RealD nn = norm2(v);
|
||||
nn = sqrt(nn);
|
||||
v = v * (1.0/nn);
|
||||
return nn;
|
||||
}
|
||||
|
||||
RealD operator()(LinearOperatorBase<Field> &HermOp, const Field &src)
|
||||
{
|
||||
GridBase *grid = src._grid;
|
||||
|
||||
// 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_EST_ = 50;
|
||||
|
||||
for (int i=0;i<_MAX_ITER_EST_;i++) {
|
||||
|
||||
normalise(src_n);
|
||||
HermOp.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.01) || (i==_MAX_ITER_EST_-1) ) {
|
||||
evalMaxApprox = na;
|
||||
return evalMaxApprox;
|
||||
}
|
||||
evalMaxApprox = na;
|
||||
std::cout << GridLogMessage << " Approximation of largest eigenvalue: " << evalMaxApprox << std::endl;
|
||||
src_n = tmp;
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
@ -1,486 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/SchurRedBlack.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_SCHUR_RED_BLACK_H
|
||||
#define GRID_SCHUR_RED_BLACK_H
|
||||
|
||||
|
||||
/*
|
||||
* Red black Schur decomposition
|
||||
*
|
||||
* M = (Mee Meo) = (1 0 ) (Mee 0 ) (1 Mee^{-1} Meo)
|
||||
* (Moe Moo) (Moe Mee^-1 1 ) (0 Moo-Moe Mee^-1 Meo) (0 1 )
|
||||
* = L D U
|
||||
*
|
||||
* L^-1 = (1 0 )
|
||||
* (-MoeMee^{-1} 1 )
|
||||
* L^{dag} = ( 1 Mee^{-dag} Moe^{dag} )
|
||||
* ( 0 1 )
|
||||
* L^{-d} = ( 1 -Mee^{-dag} Moe^{dag} )
|
||||
* ( 0 1 )
|
||||
*
|
||||
* U^-1 = (1 -Mee^{-1} Meo)
|
||||
* (0 1 )
|
||||
* U^{dag} = ( 1 0)
|
||||
* (Meo^dag Mee^{-dag} 1)
|
||||
* U^{-dag} = ( 1 0)
|
||||
* (-Meo^dag Mee^{-dag} 1)
|
||||
***********************
|
||||
* M psi = eta
|
||||
***********************
|
||||
*Odd
|
||||
* i) D_oo psi_o = L^{-1} eta_o
|
||||
* 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
|
||||
* ii) Mee psi_e + Meo psi_o = src_e
|
||||
*
|
||||
* => 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 {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Use base class to share code
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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 SchurRedBlackBase {
|
||||
protected:
|
||||
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||
OperatorFunction<Field> & _HermitianRBSolver;
|
||||
int CBfactorise;
|
||||
bool subGuess;
|
||||
bool useSolnAsInitGuess; // if true user-supplied solution vector is used as initial guess for solver
|
||||
public:
|
||||
|
||||
SchurRedBlackBase(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
|
||||
const bool _solnAsInitGuess = false) :
|
||||
_HermitianRBSolver(HermitianRBSolver),
|
||||
useSolnAsInitGuess(_solnAsInitGuess)
|
||||
{
|
||||
CBfactorise = 0;
|
||||
subtractGuess(initSubGuess);
|
||||
};
|
||||
void subtractGuess(const bool initSubGuess)
|
||||
{
|
||||
subGuess = initSubGuess;
|
||||
}
|
||||
bool isSubtractGuess(void)
|
||||
{
|
||||
return subGuess;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Shared code
|
||||
/////////////////////////////////////////////////////////////
|
||||
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
||||
ZeroGuesser<Field> guess;
|
||||
(*this)(_Matrix,in,out,guess);
|
||||
}
|
||||
void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out)
|
||||
{
|
||||
ZeroGuesser<Field> guess;
|
||||
(*this)(_Matrix,in,out,guess);
|
||||
}
|
||||
|
||||
template<class Guesser>
|
||||
void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out,Guesser &guess)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
int nblock = in.size();
|
||||
|
||||
std::vector<Field> src_o(nblock,grid);
|
||||
std::vector<Field> sol_o(nblock,grid);
|
||||
|
||||
std::vector<Field> guess_save;
|
||||
|
||||
Field resid(fgrid);
|
||||
Field tmp(grid);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Prepare RedBlack source
|
||||
////////////////////////////////////////////////
|
||||
for(int b=0;b<nblock;b++){
|
||||
RedBlackSource(_Matrix,in[b],tmp,src_o[b]);
|
||||
}
|
||||
////////////////////////////////////////////////
|
||||
// Make the guesses
|
||||
////////////////////////////////////////////////
|
||||
if ( subGuess ) guess_save.resize(nblock,grid);
|
||||
|
||||
for(int b=0;b<nblock;b++){
|
||||
if(useSolnAsInitGuess) {
|
||||
pickCheckerboard(Odd, sol_o[b], out[b]);
|
||||
} else {
|
||||
guess(src_o[b],sol_o[b]);
|
||||
}
|
||||
|
||||
if ( subGuess ) {
|
||||
guess_save[b] = sol_o[b];
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Call the block solver
|
||||
//////////////////////////////////////////////////////////////
|
||||
std::cout<<GridLogMessage << "SchurRedBlackBase calling the solver for "<<nblock<<" RHS" <<std::endl;
|
||||
RedBlackSolve(_Matrix,src_o,sol_o);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// A2A boolean behavioural control & reconstruct other checkerboard
|
||||
////////////////////////////////////////////////
|
||||
for(int b=0;b<nblock;b++) {
|
||||
|
||||
if (subGuess) sol_o[b] = sol_o[b] - guess_save[b];
|
||||
|
||||
///////// Needs even source //////////////
|
||||
pickCheckerboard(Even,tmp,in[b]);
|
||||
RedBlackSolution(_Matrix,sol_o[b],tmp,out[b]);
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Check unprec residual if possible
|
||||
/////////////////////////////////////////////////
|
||||
if ( ! subGuess ) {
|
||||
_Matrix.M(out[b],resid);
|
||||
resid = resid-in[b];
|
||||
RealD ns = norm2(in[b]);
|
||||
RealD nr = norm2(resid);
|
||||
|
||||
std::cout<<GridLogMessage<< "SchurRedBlackBase solver true unprec resid["<<b<<"] "<<std::sqrt(nr/ns) << std::endl;
|
||||
} else {
|
||||
std::cout<<GridLogMessage<< "SchurRedBlackBase Guess subtracted after solve["<<b<<"] " << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
template<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();
|
||||
|
||||
Field resid(fgrid);
|
||||
Field src_o(grid);
|
||||
Field src_e(grid);
|
||||
Field sol_o(grid);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// RedBlack source
|
||||
////////////////////////////////////////////////
|
||||
RedBlackSource(_Matrix,in,src_e,src_o);
|
||||
|
||||
////////////////////////////////
|
||||
// Construct the guess
|
||||
////////////////////////////////
|
||||
if(useSolnAsInitGuess) {
|
||||
pickCheckerboard(Odd, sol_o, out);
|
||||
} else {
|
||||
guess(src_o,sol_o);
|
||||
}
|
||||
|
||||
Field guess_save(grid);
|
||||
guess_save = sol_o;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Call the red-black solver
|
||||
//////////////////////////////////////////////////////////////
|
||||
RedBlackSolve(_Matrix,src_o,sol_o);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Fionn A2A boolean behavioural control
|
||||
////////////////////////////////////////////////
|
||||
if (subGuess) sol_o= sol_o-guess_save;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// RedBlack solution needs the even source
|
||||
///////////////////////////////////////////////////
|
||||
RedBlackSolution(_Matrix,sol_o,src_e,out);
|
||||
|
||||
// Verify the unprec residual
|
||||
if ( ! subGuess ) {
|
||||
_Matrix.M(out,resid);
|
||||
resid = resid-in;
|
||||
RealD ns = norm2(in);
|
||||
RealD nr = norm2(resid);
|
||||
|
||||
std::cout<<GridLogMessage << "SchurRedBlackBase solver true unprec resid "<< std::sqrt(nr/ns) << std::endl;
|
||||
} else {
|
||||
std::cout << GridLogMessage << "SchurRedBlackBase Guess subtracted after solve." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Override in derived.
|
||||
/////////////////////////////////////////////////////////////
|
||||
virtual void RedBlackSource (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) =0;
|
||||
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) =0;
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o) =0;
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)=0;
|
||||
|
||||
};
|
||||
|
||||
template<class Field> class SchurRedBlackStaggeredSolve : public SchurRedBlackBase<Field> {
|
||||
public:
|
||||
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||
|
||||
SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
|
||||
const bool _solnAsInitGuess = false)
|
||||
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Override RedBlack specialisation
|
||||
//////////////////////////////////////////////////////
|
||||
virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
Field tmp(grid);
|
||||
Field Mtmp(grid);
|
||||
|
||||
pickCheckerboard(Even,src_e,src);
|
||||
pickCheckerboard(Odd ,src_o,src);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// 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);
|
||||
|
||||
_Matrix.Mooee(tmp,src_o); // Extra factor of "m" in source from dumb choice of matrix norm.
|
||||
}
|
||||
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e_c,Field &sol)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
Field tmp(grid);
|
||||
Field sol_e(grid);
|
||||
Field src_e(grid);
|
||||
|
||||
src_e = src_e_c; // Const correctness
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// 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(sol,sol_e); assert( sol_e.checkerboard ==Even);
|
||||
setCheckerboard(sol,sol_o); assert( sol_o.checkerboard ==Odd );
|
||||
}
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
|
||||
{
|
||||
SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
||||
};
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
|
||||
{
|
||||
SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||
}
|
||||
};
|
||||
template<class Field> using SchurRedBlackStagSolve = SchurRedBlackStaggeredSolve<Field>;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Site diagonal has Mooee on it.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Field> class SchurRedBlackDiagMooeeSolve : public SchurRedBlackBase<Field> {
|
||||
public:
|
||||
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||
|
||||
SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
|
||||
const bool _solnAsInitGuess = false)
|
||||
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Override RedBlack specialisation
|
||||
//////////////////////////////////////////////////////
|
||||
virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
Field tmp(grid);
|
||||
Field Mtmp(grid);
|
||||
|
||||
pickCheckerboard(Even,src_e,src);
|
||||
pickCheckerboard(Odd ,src_o,src);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// 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
|
||||
SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
||||
|
||||
}
|
||||
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
Field tmp(grid);
|
||||
Field sol_e(grid);
|
||||
Field src_e_i(grid);
|
||||
///////////////////////////////////////////////////
|
||||
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||
///////////////////////////////////////////////////
|
||||
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
||||
src_e_i = src_e-tmp; assert( src_e_i.checkerboard ==Even);
|
||||
_Matrix.MooeeInv(src_e_i,sol_e); assert( sol_e.checkerboard ==Even);
|
||||
|
||||
setCheckerboard(sol,sol_e); assert( sol_e.checkerboard ==Even);
|
||||
setCheckerboard(sol,sol_o); assert( sol_o.checkerboard ==Odd );
|
||||
}
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
|
||||
{
|
||||
SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
||||
};
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
|
||||
{
|
||||
SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Site diagonal is identity, right preconditioned by Mee^inv
|
||||
// ( 1 - Meo Moo^inv Moe Mee^inv ) phi =( 1 - Meo Moo^inv Moe Mee^inv ) Mee psi = = eta = eta
|
||||
//=> psi = MeeInv phi
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Field> class SchurRedBlackDiagTwoSolve : public SchurRedBlackBase<Field> {
|
||||
public:
|
||||
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Wrap the usual normal equations Schur trick
|
||||
/////////////////////////////////////////////////////
|
||||
SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
|
||||
const bool _solnAsInitGuess = false)
|
||||
: SchurRedBlackBase<Field>(HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
|
||||
|
||||
virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
|
||||
Field tmp(grid);
|
||||
Field Mtmp(grid);
|
||||
|
||||
pickCheckerboard(Even,src_e,src);
|
||||
pickCheckerboard(Odd ,src_o,src);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// 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);
|
||||
}
|
||||
|
||||
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)
|
||||
{
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
Field sol_o_i(grid);
|
||||
Field tmp(grid);
|
||||
Field sol_e(grid);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// MooeeInv due to pecond
|
||||
////////////////////////////////////////////////
|
||||
_Matrix.MooeeInv(sol_o,tmp);
|
||||
sol_o_i = tmp;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||
///////////////////////////////////////////////////
|
||||
_Matrix.Meooe(sol_o_i,tmp); assert( tmp.checkerboard ==Even);
|
||||
tmp = src_e-tmp; assert( src_e.checkerboard ==Even);
|
||||
_Matrix.MooeeInv(tmp,sol_e); assert( sol_e.checkerboard ==Even);
|
||||
|
||||
setCheckerboard(sol,sol_e); assert( sol_e.checkerboard ==Even);
|
||||
setCheckerboard(sol,sol_o_i); assert( sol_o_i.checkerboard ==Odd );
|
||||
};
|
||||
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
|
||||
{
|
||||
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||
};
|
||||
virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
|
||||
{
|
||||
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,3 +0,0 @@
|
||||
#include <Grid/GridCore.h>
|
||||
|
||||
int Grid::BinaryIO::latticeWriteMaxRetry = -1;
|
@ -1,237 +0,0 @@
|
||||
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/qcd/action/fermion/FourierAcceleratedPV.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Christoph Lehner (lifted with permission by Peter Boyle, brought back to Grid)
|
||||
Author: Peter Boyle <pabobyle@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 */
|
||||
#pragma once
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
template<typename M>
|
||||
void get_real_const_bc(M& m, RealD& _b, RealD& _c) {
|
||||
ComplexD b,c;
|
||||
b=m.bs[0];
|
||||
c=m.cs[0];
|
||||
std::cout << GridLogMessage << "b=" << b << ", c=" << c << std::endl;
|
||||
for (size_t i=1;i<m.bs.size();i++) {
|
||||
assert(m.bs[i] == b);
|
||||
assert(m.cs[i] == c);
|
||||
}
|
||||
assert(b.imag() == 0.0);
|
||||
assert(c.imag() == 0.0);
|
||||
_b = b.real();
|
||||
_c = c.real();
|
||||
}
|
||||
|
||||
|
||||
template<typename Vi, typename M, typename G>
|
||||
class FourierAcceleratedPV {
|
||||
public:
|
||||
|
||||
ConjugateGradient<Vi> &cg;
|
||||
M& dwfPV;
|
||||
G& Umu;
|
||||
GridCartesian* grid5D;
|
||||
GridRedBlackCartesian* gridRB5D;
|
||||
int group_in_s;
|
||||
|
||||
FourierAcceleratedPV(M& _dwfPV, G& _Umu, ConjugateGradient<Vi> &_cg, int _group_in_s = 2)
|
||||
: dwfPV(_dwfPV), Umu(_Umu), cg(_cg), group_in_s(_group_in_s)
|
||||
{
|
||||
assert( dwfPV.FermionGrid()->_fdimensions[0] % (2*group_in_s) == 0);
|
||||
grid5D = QCD::SpaceTimeGrid::makeFiveDimGrid(2*group_in_s, (GridCartesian*)Umu._grid);
|
||||
gridRB5D = QCD::SpaceTimeGrid::makeFiveDimRedBlackGrid(2*group_in_s, (GridCartesian*)Umu._grid);
|
||||
}
|
||||
|
||||
void rotatePV(const Vi& _src, Vi& dst, bool forward) const {
|
||||
|
||||
GridStopWatch gsw1, gsw2;
|
||||
|
||||
typedef typename Vi::scalar_type Coeff_t;
|
||||
int Ls = dst._grid->_fdimensions[0];
|
||||
|
||||
Vi _tmp(dst._grid);
|
||||
double phase = M_PI / (double)Ls;
|
||||
Coeff_t bzero(0.0,0.0);
|
||||
|
||||
FFT theFFT((GridCartesian*)dst._grid);
|
||||
|
||||
if (!forward) {
|
||||
gsw1.Start();
|
||||
for (int s=0;s<Ls;s++) {
|
||||
Coeff_t a(::cos(phase*s),-::sin(phase*s));
|
||||
axpby_ssp(_tmp,a,_src,bzero,_src,s,s);
|
||||
}
|
||||
gsw1.Stop();
|
||||
|
||||
gsw2.Start();
|
||||
theFFT.FFT_dim(dst,_tmp,0,FFT::forward);
|
||||
gsw2.Stop();
|
||||
|
||||
} else {
|
||||
|
||||
gsw2.Start();
|
||||
theFFT.FFT_dim(_tmp,_src,0,FFT::backward);
|
||||
gsw2.Stop();
|
||||
|
||||
gsw1.Start();
|
||||
for (int s=0;s<Ls;s++) {
|
||||
Coeff_t a(::cos(phase*s),::sin(phase*s));
|
||||
axpby_ssp(dst,a,_tmp,bzero,_tmp,s,s);
|
||||
}
|
||||
gsw1.Stop();
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "Timing rotatePV: " << gsw1.Elapsed() << ", " << gsw2.Elapsed() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void pvInv(const Vi& _src, Vi& _dst) const {
|
||||
|
||||
std::cout << GridLogMessage << "Fourier-Accelerated Outer Pauli Villars"<<std::endl;
|
||||
|
||||
typedef typename Vi::scalar_type Coeff_t;
|
||||
int Ls = _dst._grid->_fdimensions[0];
|
||||
|
||||
GridStopWatch gswT;
|
||||
gswT.Start();
|
||||
|
||||
RealD b,c;
|
||||
get_real_const_bc(dwfPV,b,c);
|
||||
RealD M5 = dwfPV.M5;
|
||||
|
||||
// U(true) Rightinv TMinv U(false) = Minv
|
||||
|
||||
Vi _src_diag(_dst._grid);
|
||||
Vi _src_diag_slice(dwfPV.GaugeGrid());
|
||||
Vi _dst_diag_slice(dwfPV.GaugeGrid());
|
||||
Vi _src_diag_slices(grid5D);
|
||||
Vi _dst_diag_slices(grid5D);
|
||||
Vi _dst_diag(_dst._grid);
|
||||
|
||||
rotatePV(_src,_src_diag,false);
|
||||
|
||||
// now do TM solves
|
||||
Gamma G5(Gamma::Algebra::Gamma5);
|
||||
|
||||
GridStopWatch gswA, gswB;
|
||||
|
||||
gswA.Start();
|
||||
|
||||
typedef typename M::Impl_t Impl;
|
||||
//WilsonTMFermion<Impl> tm(x.Umu,*x.UGridF,*x.UrbGridF,0.0,0.0,solver_outer.parent.par.wparams_f);
|
||||
std::vector<RealD> vmass(grid5D->_fdimensions[0],0.0);
|
||||
std::vector<RealD> vmu(grid5D->_fdimensions[0],0.0);
|
||||
|
||||
WilsonTMFermion5D<Impl> tm(Umu,*grid5D,*gridRB5D,
|
||||
*(GridCartesian*)dwfPV.GaugeGrid(),
|
||||
*(GridRedBlackCartesian*)dwfPV.GaugeRedBlackGrid(),
|
||||
vmass,vmu);
|
||||
|
||||
//SchurRedBlackDiagTwoSolve<Vi> sol(cg);
|
||||
SchurRedBlackDiagMooeeSolve<Vi> sol(cg); // same performance as DiagTwo
|
||||
gswA.Stop();
|
||||
|
||||
gswB.Start();
|
||||
|
||||
for (int sgroup=0;sgroup<Ls/2/group_in_s;sgroup++) {
|
||||
|
||||
for (int sidx=0;sidx<group_in_s;sidx++) {
|
||||
|
||||
int s = sgroup*group_in_s + sidx;
|
||||
int sprime = Ls-s-1;
|
||||
|
||||
RealD phase = M_PI / (RealD)Ls * (2.0 * s + 1.0);
|
||||
RealD cosp = ::cos(phase);
|
||||
RealD sinp = ::sin(phase);
|
||||
RealD denom = b*b + c*c + 2.0*b*c*cosp;
|
||||
RealD mass = -(b*b*M5 + c*(1.0 - cosp + c*M5) + b*(-1.0 + cosp + 2.0*c*cosp*M5))/denom;
|
||||
RealD mu = (b+c)*sinp/denom;
|
||||
|
||||
vmass[2*sidx + 0] = mass;
|
||||
vmass[2*sidx + 1] = mass;
|
||||
vmu[2*sidx + 0] = mu;
|
||||
vmu[2*sidx + 1] = -mu;
|
||||
|
||||
}
|
||||
|
||||
tm.update(vmass,vmu);
|
||||
|
||||
for (int sidx=0;sidx<group_in_s;sidx++) {
|
||||
|
||||
int s = sgroup*group_in_s + sidx;
|
||||
int sprime = Ls-s-1;
|
||||
|
||||
ExtractSlice(_src_diag_slice,_src_diag,s,0);
|
||||
InsertSlice(_src_diag_slice,_src_diag_slices,2*sidx + 0,0);
|
||||
|
||||
ExtractSlice(_src_diag_slice,_src_diag,sprime,0);
|
||||
InsertSlice(_src_diag_slice,_src_diag_slices,2*sidx + 1,0);
|
||||
|
||||
}
|
||||
|
||||
GridStopWatch gsw;
|
||||
gsw.Start();
|
||||
_dst_diag_slices = zero; // zero guess
|
||||
sol(tm,_src_diag_slices,_dst_diag_slices);
|
||||
gsw.Stop();
|
||||
std::cout << GridLogMessage << "Solve[sgroup=" << sgroup << "] completed in " << gsw.Elapsed() << ", " << gswA.Elapsed() << std::endl;
|
||||
|
||||
for (int sidx=0;sidx<group_in_s;sidx++) {
|
||||
|
||||
int s = sgroup*group_in_s + sidx;
|
||||
int sprime = Ls-s-1;
|
||||
|
||||
RealD phase = M_PI / (RealD)Ls * (2.0 * s + 1.0);
|
||||
RealD cosp = ::cos(phase);
|
||||
RealD sinp = ::sin(phase);
|
||||
|
||||
// now rotate with inverse of
|
||||
Coeff_t pA = b + c*cosp;
|
||||
Coeff_t pB = - Coeff_t(0.0,1.0)*c*sinp;
|
||||
Coeff_t pABden = pA*pA - pB*pB;
|
||||
// (pA + pB * G5) * (pA - pB*G5) = (pA^2 - pB^2)
|
||||
|
||||
ExtractSlice(_dst_diag_slice,_dst_diag_slices,2*sidx + 0,0);
|
||||
_dst_diag_slice = (pA/pABden) * _dst_diag_slice - (pB/pABden) * (G5 * _dst_diag_slice);
|
||||
InsertSlice(_dst_diag_slice,_dst_diag,s,0);
|
||||
|
||||
ExtractSlice(_dst_diag_slice,_dst_diag_slices,2*sidx + 1,0);
|
||||
_dst_diag_slice = (pA/pABden) * _dst_diag_slice + (pB/pABden) * (G5 * _dst_diag_slice);
|
||||
InsertSlice(_dst_diag_slice,_dst_diag,sprime,0);
|
||||
}
|
||||
}
|
||||
gswB.Stop();
|
||||
|
||||
rotatePV(_dst_diag,_dst,true);
|
||||
|
||||
gswT.Stop();
|
||||
std::cout << GridLogMessage << "PV completed in " << gswT.Elapsed() << " (Setup: " << gswA.Elapsed() << ", s-loop: " << gswB.Elapsed() << ")" << std::endl;
|
||||
}
|
||||
|
||||
};
|
||||
}}
|
@ -1,193 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/MADWF.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 */
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
template <class Fieldi, class Fieldo,IfNotSame<Fieldi,Fieldo> X=0>
|
||||
inline void convert(const Fieldi &from,Fieldo &to)
|
||||
{
|
||||
precisionChange(to,from);
|
||||
}
|
||||
template <class Fieldi, class Fieldo,IfSame<Fieldi,Fieldo> X=0>
|
||||
inline void convert(const Fieldi &from,Fieldo &to)
|
||||
{
|
||||
to=from;
|
||||
}
|
||||
|
||||
template<class Matrixo,class Matrixi,class PVinverter,class SchurSolver, class Guesser>
|
||||
class MADWF
|
||||
{
|
||||
private:
|
||||
typedef typename Matrixo::FermionField FermionFieldo;
|
||||
typedef typename Matrixi::FermionField FermionFieldi;
|
||||
|
||||
PVinverter & PauliVillarsSolvero;// For the outer field
|
||||
SchurSolver & SchurSolveri; // For the inner approx field
|
||||
Guesser & Guesseri; // To deflate the inner approx solves
|
||||
|
||||
Matrixo & Mato; // Action object for outer
|
||||
Matrixi & Mati; // Action object for inner
|
||||
|
||||
RealD target_resid;
|
||||
int maxiter;
|
||||
public:
|
||||
|
||||
MADWF(Matrixo &_Mato,
|
||||
Matrixi &_Mati,
|
||||
PVinverter &_PauliVillarsSolvero,
|
||||
SchurSolver &_SchurSolveri,
|
||||
Guesser & _Guesseri,
|
||||
RealD resid,
|
||||
int _maxiter) :
|
||||
|
||||
Mato(_Mato),Mati(_Mati),
|
||||
SchurSolveri(_SchurSolveri),
|
||||
PauliVillarsSolvero(_PauliVillarsSolvero),Guesseri(_Guesseri)
|
||||
{
|
||||
target_resid=resid;
|
||||
maxiter =_maxiter;
|
||||
};
|
||||
|
||||
void operator() (const FermionFieldo &src4,FermionFieldo &sol5)
|
||||
{
|
||||
std::cout << GridLogMessage<< " ************************************************" << std::endl;
|
||||
std::cout << GridLogMessage<< " MADWF-like algorithm " << std::endl;
|
||||
std::cout << GridLogMessage<< " ************************************************" << std::endl;
|
||||
|
||||
FermionFieldi c0i(Mati.GaugeGrid()); // 4d
|
||||
FermionFieldi y0i(Mati.GaugeGrid()); // 4d
|
||||
FermionFieldo c0 (Mato.GaugeGrid()); // 4d
|
||||
FermionFieldo y0 (Mato.GaugeGrid()); // 4d
|
||||
|
||||
FermionFieldo A(Mato.FermionGrid()); // Temporary outer
|
||||
FermionFieldo B(Mato.FermionGrid()); // Temporary outer
|
||||
FermionFieldo b(Mato.FermionGrid()); // 5d source
|
||||
|
||||
FermionFieldo c(Mato.FermionGrid()); // PVinv source; reused so store
|
||||
FermionFieldo defect(Mato.FermionGrid()); // 5d source
|
||||
|
||||
FermionFieldi ci(Mati.FermionGrid());
|
||||
FermionFieldi yi(Mati.FermionGrid());
|
||||
FermionFieldi xi(Mati.FermionGrid());
|
||||
FermionFieldi srci(Mati.FermionGrid());
|
||||
FermionFieldi Ai(Mati.FermionGrid());
|
||||
|
||||
RealD m=Mati.Mass();
|
||||
|
||||
///////////////////////////////////////
|
||||
//Import source, include Dminus factors
|
||||
///////////////////////////////////////
|
||||
Mato.ImportPhysicalFermionSource(src4,b);
|
||||
std::cout << GridLogMessage << " src4 " <<norm2(src4)<<std::endl;
|
||||
std::cout << GridLogMessage << " b " <<norm2(b)<<std::endl;
|
||||
|
||||
defect = b;
|
||||
sol5=zero;
|
||||
for (int i=0;i<maxiter;i++) {
|
||||
|
||||
///////////////////////////////////////
|
||||
// Set up c0 from current defect
|
||||
///////////////////////////////////////
|
||||
PauliVillarsSolvero(Mato,defect,A);
|
||||
Mato.Pdag(A,c);
|
||||
ExtractSlice(c0, c, 0 , 0);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Solve the inner system with surface term c0
|
||||
////////////////////////////////////////////////
|
||||
ci = zero;
|
||||
convert(c0,c0i); // Possible precison change
|
||||
InsertSlice(c0i,ci,0, 0);
|
||||
|
||||
// Dwm P y = Dwm x = D(1) P (c0,0,0,0)^T
|
||||
Mati.P(ci,Ai);
|
||||
Mati.SetMass(1.0); Mati.M(Ai,srci); Mati.SetMass(m);
|
||||
SchurSolveri(Mati,srci,xi,Guesseri);
|
||||
Mati.Pdag(xi,yi);
|
||||
ExtractSlice(y0i, yi, 0 , 0);
|
||||
convert(y0i,y0); // Possible precision change
|
||||
|
||||
//////////////////////////////////////
|
||||
// Propagate solution back to outer system
|
||||
// Build Pdag PV^-1 Dm P [-sol4,c2,c3... cL]
|
||||
//////////////////////////////////////
|
||||
c0 = - y0;
|
||||
InsertSlice(c0, c, 0 , 0);
|
||||
|
||||
/////////////////////////////
|
||||
// Reconstruct the bulk solution Pdag PV^-1 Dm P
|
||||
/////////////////////////////
|
||||
Mato.P(c,B);
|
||||
Mato.M(B,A);
|
||||
PauliVillarsSolvero(Mato,A,B);
|
||||
Mato.Pdag(B,A);
|
||||
|
||||
//////////////////////////////
|
||||
// Reinsert surface prop
|
||||
//////////////////////////////
|
||||
InsertSlice(y0,A,0,0);
|
||||
|
||||
//////////////////////////////
|
||||
// Convert from y back to x
|
||||
//////////////////////////////
|
||||
Mato.P(A,B);
|
||||
|
||||
// sol5' = sol5 + M^-1 defect
|
||||
// = sol5 + M^-1 src - M^-1 M sol5 ...
|
||||
sol5 = sol5 + B;
|
||||
std::cout << GridLogMessage << "***************************************" <<std::endl;
|
||||
std::cout << GridLogMessage << " Sol5 update "<<std::endl;
|
||||
std::cout << GridLogMessage << "***************************************" <<std::endl;
|
||||
std::cout << GridLogMessage << " Sol5 now "<<norm2(sol5)<<std::endl;
|
||||
std::cout << GridLogMessage << " delta "<<norm2(B)<<std::endl;
|
||||
|
||||
// New defect = b - M sol5
|
||||
Mato.M(sol5,A);
|
||||
defect = b - A;
|
||||
|
||||
std::cout << GridLogMessage << " defect "<<norm2(defect)<<std::endl;
|
||||
|
||||
double resid = ::sqrt(norm2(defect) / norm2(b));
|
||||
std::cout << GridLogMessage << "Residual " << i << ": " << resid << std::endl;
|
||||
std::cout << GridLogMessage << "***************************************" <<std::endl;
|
||||
|
||||
if (resid < target_resid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "MADWF : Exceeded maxiter "<<std::endl;
|
||||
assert(0);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
@ -1,95 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/SchurRedBlack.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 */
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
template<class Field>
|
||||
class PauliVillarsSolverUnprec
|
||||
{
|
||||
public:
|
||||
ConjugateGradient<Field> & CG;
|
||||
PauliVillarsSolverUnprec( ConjugateGradient<Field> &_CG) : CG(_CG){};
|
||||
|
||||
template<class Matrix>
|
||||
void operator() (Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
Field A (_Matrix.FermionGrid());
|
||||
|
||||
MdagMLinearOperator<Matrix,Field> HermOp(_Matrix);
|
||||
|
||||
_Matrix.SetMass(1.0);
|
||||
_Matrix.Mdag(src,A);
|
||||
CG(HermOp,A,sol);
|
||||
_Matrix.SetMass(m);
|
||||
};
|
||||
};
|
||||
|
||||
template<class Field,class SchurSolverType>
|
||||
class PauliVillarsSolverRBprec
|
||||
{
|
||||
public:
|
||||
SchurSolverType & SchurSolver;
|
||||
PauliVillarsSolverRBprec( SchurSolverType &_SchurSolver) : SchurSolver(_SchurSolver){};
|
||||
|
||||
template<class Matrix>
|
||||
void operator() (Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
Field A (_Matrix.FermionGrid());
|
||||
|
||||
_Matrix.SetMass(1.0);
|
||||
SchurSolver(_Matrix,src,sol);
|
||||
_Matrix.SetMass(m);
|
||||
};
|
||||
};
|
||||
|
||||
template<class Field,class GaugeField>
|
||||
class PauliVillarsSolverFourierAccel
|
||||
{
|
||||
public:
|
||||
GaugeField & Umu;
|
||||
ConjugateGradient<Field> & CG;
|
||||
|
||||
PauliVillarsSolverFourierAccel(GaugeField &_Umu,ConjugateGradient<Field> &_CG) : Umu(_Umu), CG(_CG)
|
||||
{
|
||||
};
|
||||
|
||||
template<class Matrix>
|
||||
void operator() (Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
FourierAcceleratedPV<Field, Matrix, typename Matrix::GaugeField > faPV(_Matrix,Umu,CG) ;
|
||||
faPV.pvInv(src,sol);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/SchurRedBlack.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 */
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
template<class Field,class PVinverter> class Reconstruct5DfromPhysical {
|
||||
private:
|
||||
PVinverter & PauliVillarsSolver;
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// First cut works, 10 Oct 2018.
|
||||
//
|
||||
// Must form a plan to get this into production for Zmobius acceleration
|
||||
// of the Mobius exact AMA corrections.
|
||||
//
|
||||
// TODO : understand absence of contact term in eqns in Hantao's thesis
|
||||
// sol4 is contact term subtracted, but thesis & Brower's paper suggests not.
|
||||
//
|
||||
// Step 1: Localise PV inverse in a routine. [DONE]
|
||||
// Step 2: Schur based PV inverse [DONE]
|
||||
// Step 3: Fourier accelerated PV inverse [DONE]
|
||||
//
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
Reconstruct5DfromPhysical(PVinverter &_PauliVillarsSolver)
|
||||
: PauliVillarsSolver(_PauliVillarsSolver)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<class Matrix>
|
||||
void PV(Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
_Matrix.SetMass(1.0);
|
||||
_Matrix.M(src,sol);
|
||||
_Matrix.SetMass(m);
|
||||
}
|
||||
template<class Matrix>
|
||||
void PVdag(Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
_Matrix.SetMass(1.0);
|
||||
_Matrix.Mdag(src,sol);
|
||||
_Matrix.SetMass(m);
|
||||
}
|
||||
template<class Matrix>
|
||||
void operator() (Matrix & _Matrix,const Field &sol4,const Field &src4, Field &sol5){
|
||||
|
||||
int Ls = _Matrix.Ls;
|
||||
|
||||
Field psi4(_Matrix.GaugeGrid());
|
||||
Field psi(_Matrix.FermionGrid());
|
||||
Field A (_Matrix.FermionGrid());
|
||||
Field B (_Matrix.FermionGrid());
|
||||
Field c (_Matrix.FermionGrid());
|
||||
|
||||
typedef typename Matrix::Coeff_t Coeff_t;
|
||||
|
||||
std::cout << GridLogMessage<< " ************************************************" << std::endl;
|
||||
std::cout << GridLogMessage<< " Reconstruct5Dprop: c.f. MADWF algorithm " << std::endl;
|
||||
std::cout << GridLogMessage<< " ************************************************" << std::endl;
|
||||
|
||||
///////////////////////////////////////
|
||||
//Import source, include Dminus factors
|
||||
///////////////////////////////////////
|
||||
_Matrix.ImportPhysicalFermionSource(src4,B);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Set up c from src4
|
||||
///////////////////////////////////////
|
||||
PauliVillarsSolver(_Matrix,B,A);
|
||||
_Matrix.Pdag(A,c);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Build Pdag PV^-1 Dm P [-sol4,c2,c3... cL]
|
||||
//////////////////////////////////////
|
||||
psi4 = - sol4;
|
||||
InsertSlice(psi4, psi, 0 , 0);
|
||||
for (int s=1;s<Ls;s++) {
|
||||
ExtractSlice(psi4,c,s,0);
|
||||
InsertSlice(psi4,psi,s,0);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// Pdag PV^-1 Dm P
|
||||
/////////////////////////////
|
||||
_Matrix.P(psi,B);
|
||||
_Matrix.M(B,A);
|
||||
PauliVillarsSolver(_Matrix,A,B);
|
||||
_Matrix.Pdag(B,A);
|
||||
|
||||
//////////////////////////////
|
||||
// Reinsert surface prop
|
||||
//////////////////////////////
|
||||
InsertSlice(sol4,A,0,0);
|
||||
|
||||
//////////////////////////////
|
||||
// Convert from y back to x
|
||||
//////////////////////////////
|
||||
_Matrix.P(A,sol5);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/qcd/action/fermion/WilsonTMFermion5D.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk> ; NB Christoph did similar in GPT
|
||||
|
||||
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 */
|
||||
#pragma once
|
||||
|
||||
#include <Grid/qcd/action/fermion/FermionCore.h>
|
||||
#include <Grid/qcd/action/fermion/WilsonFermion.h>
|
||||
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
template<class Impl>
|
||||
class WilsonTMFermion5D : public WilsonFermion5D<Impl>
|
||||
{
|
||||
public:
|
||||
INHERIT_IMPL_TYPES(Impl);
|
||||
public:
|
||||
|
||||
virtual void Instantiatable(void) {};
|
||||
|
||||
// Constructors
|
||||
WilsonTMFermion5D(GaugeField &_Umu,
|
||||
GridCartesian &Fgrid,
|
||||
GridRedBlackCartesian &Frbgrid,
|
||||
GridCartesian &Ugrid,
|
||||
GridRedBlackCartesian &Urbgrid,
|
||||
const std::vector<RealD> _mass,
|
||||
const std::vector<RealD> _mu,
|
||||
const ImplParams &p= ImplParams()
|
||||
) :
|
||||
WilsonFermion5D<Impl>(_Umu,
|
||||
Fgrid,
|
||||
Frbgrid,
|
||||
Ugrid,
|
||||
Urbgrid,
|
||||
4.0,p)
|
||||
|
||||
{
|
||||
update(_mass,_mu);
|
||||
}
|
||||
|
||||
virtual void Meooe(const FermionField &in, FermionField &out) {
|
||||
if (in.checkerboard == Odd) {
|
||||
this->DhopEO(in, out, DaggerNo);
|
||||
} else {
|
||||
this->DhopOE(in, out, DaggerNo);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MeooeDag(const FermionField &in, FermionField &out) {
|
||||
if (in.checkerboard == Odd) {
|
||||
this->DhopEO(in, out, DaggerYes);
|
||||
} else {
|
||||
this->DhopOE(in, out, DaggerYes);
|
||||
}
|
||||
}
|
||||
|
||||
// allow override for twisted mass and clover
|
||||
virtual void Mooee(const FermionField &in, FermionField &out) {
|
||||
out.checkerboard = in.checkerboard;
|
||||
//axpibg5x(out,in,a,b); // out = a*in + b*i*G5*in
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
ComplexD a = 4.0+this->mass[s];
|
||||
ComplexD b(0.0,this->mu[s]);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MooeeDag(const FermionField &in, FermionField &out) {
|
||||
out.checkerboard = in.checkerboard;
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
ComplexD a = 4.0+this->mass[s];
|
||||
ComplexD b(0.0,-this->mu[s]);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
virtual void MooeeInv(const FermionField &in, FermionField &out) {
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
RealD m = this->mass[s];
|
||||
RealD tm = this->mu[s];
|
||||
RealD mtil = 4.0+this->mass[s];
|
||||
RealD sq = mtil*mtil+tm*tm;
|
||||
ComplexD a = mtil/sq;
|
||||
ComplexD b(0.0, -tm /sq);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
virtual void MooeeInvDag(const FermionField &in, FermionField &out) {
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
RealD m = this->mass[s];
|
||||
RealD tm = this->mu[s];
|
||||
RealD mtil = 4.0+this->mass[s];
|
||||
RealD sq = mtil*mtil+tm*tm;
|
||||
ComplexD a = mtil/sq;
|
||||
ComplexD b(0.0,tm /sq);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
|
||||
virtual RealD M(const FermionField &in, FermionField &out) {
|
||||
out.checkerboard = in.checkerboard;
|
||||
this->Dhop(in, out, DaggerNo);
|
||||
FermionField tmp(out._grid);
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
ComplexD a = 4.0+this->mass[s];
|
||||
ComplexD b(0.0,this->mu[s]);
|
||||
axpbg5y_ssp(tmp,a,in,b,in,s,s);
|
||||
}
|
||||
return axpy_norm(out, 1.0, tmp, out);
|
||||
}
|
||||
|
||||
// needed for fast PV
|
||||
void update(const std::vector<RealD>& _mass, const std::vector<RealD>& _mu) {
|
||||
assert(_mass.size() == _mu.size());
|
||||
assert(_mass.size() == this->FermionGrid()->_fdimensions[0]);
|
||||
this->mass = _mass;
|
||||
this->mu = _mu;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<RealD> mu;
|
||||
std::vector<RealD> mass;
|
||||
|
||||
};
|
||||
|
||||
typedef WilsonTMFermion5D<WilsonImplF> WilsonTMFermion5DF;
|
||||
typedef WilsonTMFermion5D<WilsonImplD> WilsonTMFermion5DD;
|
||||
|
||||
}}
|
@ -1,331 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/qcd/action/gauge/Photon.h
|
||||
|
||||
Copyright (C) 2015-2018
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: James Harrison <J.Harrison@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 */
|
||||
#ifndef QCD_PHOTON_ACTION_H
|
||||
#define QCD_PHOTON_ACTION_H
|
||||
|
||||
namespace Grid{
|
||||
namespace QCD{
|
||||
|
||||
template <class S>
|
||||
class QedGImpl
|
||||
{
|
||||
public:
|
||||
typedef S Simd;
|
||||
typedef typename Simd::scalar_type Scalar;
|
||||
|
||||
template <typename vtype>
|
||||
using iImplGaugeLink = iScalar<iScalar<iScalar<vtype>>>;
|
||||
template <typename vtype>
|
||||
using iImplGaugeField = iVector<iScalar<iScalar<vtype>>, Nd>;
|
||||
|
||||
typedef iImplGaugeLink<Simd> SiteLink;
|
||||
typedef iImplGaugeField<Simd> SiteField;
|
||||
typedef SiteLink SiteComplex;
|
||||
|
||||
typedef Lattice<SiteLink> LinkField;
|
||||
typedef Lattice<SiteField> Field;
|
||||
typedef Field ComplexField;
|
||||
};
|
||||
|
||||
typedef QedGImpl<vComplex> QedGImplR;
|
||||
|
||||
template <class GImpl>
|
||||
class Photon
|
||||
{
|
||||
public:
|
||||
INHERIT_GIMPL_TYPES(GImpl);
|
||||
typedef typename SiteGaugeLink::scalar_object ScalarSite;
|
||||
typedef typename ScalarSite::scalar_type ScalarComplex;
|
||||
GRID_SERIALIZABLE_ENUM(Gauge, undef, feynman, 1, coulomb, 2, landau, 3);
|
||||
GRID_SERIALIZABLE_ENUM(ZmScheme, undef, qedL, 1, qedTL, 2);
|
||||
public:
|
||||
Photon(GridBase *grid, Gauge gauge, ZmScheme zmScheme, std::vector<Real> improvement);
|
||||
Photon(GridBase *grid, Gauge gauge, ZmScheme zmScheme);
|
||||
virtual ~Photon(void) = default;
|
||||
void FreePropagator(const GaugeField &in, GaugeField &out);
|
||||
void MomentumSpacePropagator(const GaugeField &in, GaugeField &out);
|
||||
void StochasticWeight(GaugeLinkField &weight);
|
||||
void StochasticField(GaugeField &out, GridParallelRNG &rng);
|
||||
void StochasticField(GaugeField &out, GridParallelRNG &rng,
|
||||
const GaugeLinkField &weight);
|
||||
void UnitField(GaugeField &out);
|
||||
private:
|
||||
void makeSpatialNorm(LatticeInteger &spNrm);
|
||||
void makeKHat(std::vector<GaugeLinkField> &khat);
|
||||
void makeInvKHatSquared(GaugeLinkField &out);
|
||||
void zmSub(GaugeLinkField &out);
|
||||
void transverseProjectSpatial(GaugeField &out);
|
||||
void gaugeTransform(GaugeField &out);
|
||||
private:
|
||||
GridBase *grid_;
|
||||
Gauge gauge_;
|
||||
ZmScheme zmScheme_;
|
||||
std::vector<Real> improvement_;
|
||||
};
|
||||
|
||||
typedef Photon<QedGImplR> PhotonR;
|
||||
|
||||
template<class GImpl>
|
||||
Photon<GImpl>::Photon(GridBase *grid, Gauge gauge, ZmScheme zmScheme,
|
||||
std::vector<Real> improvements)
|
||||
: grid_(grid), gauge_(gauge), zmScheme_(zmScheme), improvement_(improvements)
|
||||
{}
|
||||
|
||||
template<class GImpl>
|
||||
Photon<GImpl>::Photon(GridBase *grid, Gauge gauge, ZmScheme zmScheme)
|
||||
: Photon(grid, gauge, zmScheme, std::vector<Real>())
|
||||
{}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::FreePropagator(const GaugeField &in, GaugeField &out)
|
||||
{
|
||||
FFT theFFT(dynamic_cast<GridCartesian *>(grid_));
|
||||
GaugeField in_k(grid_);
|
||||
GaugeField prop_k(grid_);
|
||||
|
||||
theFFT.FFT_all_dim(in_k, in, FFT::forward);
|
||||
MomentumSpacePropagator(prop_k, in_k);
|
||||
theFFT.FFT_all_dim(out, prop_k, FFT::backward);
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::makeSpatialNorm(LatticeInteger &spNrm)
|
||||
{
|
||||
LatticeInteger coor(grid_);
|
||||
std::vector<int> l = grid_->FullDimensions();
|
||||
|
||||
spNrm = zero;
|
||||
for(int mu = 0; mu < grid_->Nd() - 1; mu++)
|
||||
{
|
||||
LatticeCoordinate(coor, mu);
|
||||
coor = where(coor < Integer(l[mu]/2), coor, coor - Integer(l[mu]));
|
||||
spNrm = spNrm + coor*coor;
|
||||
}
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::makeKHat(std::vector<GaugeLinkField> &khat)
|
||||
{
|
||||
const unsigned int nd = grid_->Nd();
|
||||
std::vector<int> l = grid_->FullDimensions();
|
||||
Complex ci(0., 1.);
|
||||
|
||||
khat.resize(nd, grid_);
|
||||
for (unsigned int mu = 0; mu < nd; ++mu)
|
||||
{
|
||||
Real piL = M_PI/l[mu];
|
||||
|
||||
LatticeCoordinate(khat[mu], mu);
|
||||
khat[mu] = exp(piL*ci*khat[mu])*2.*sin(piL*khat[mu]);
|
||||
}
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::makeInvKHatSquared(GaugeLinkField &out)
|
||||
{
|
||||
std::vector<GaugeLinkField> khat;
|
||||
GaugeLinkField lone(grid_);
|
||||
const unsigned int nd = grid_->Nd();
|
||||
std::vector<int> zm(nd, 0);
|
||||
ScalarSite one = ScalarComplex(1., 0.), z = ScalarComplex(0., 0.);
|
||||
|
||||
out = zero;
|
||||
makeKHat(khat);
|
||||
for(int mu = 0; mu < nd; mu++)
|
||||
{
|
||||
out = out + khat[mu]*conjugate(khat[mu]);
|
||||
}
|
||||
lone = ScalarComplex(1., 0.);
|
||||
pokeSite(one, out, zm);
|
||||
out = lone/out;
|
||||
pokeSite(z, out, zm);
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::zmSub(GaugeLinkField &out)
|
||||
{
|
||||
switch (zmScheme_)
|
||||
{
|
||||
case ZmScheme::qedTL:
|
||||
{
|
||||
std::vector<int> zm(grid_->Nd(), 0);
|
||||
ScalarSite z = ScalarComplex(0., 0.);
|
||||
|
||||
pokeSite(z, out, zm);
|
||||
break;
|
||||
}
|
||||
case ZmScheme::qedL:
|
||||
{
|
||||
LatticeInteger spNrm(grid_);
|
||||
|
||||
makeSpatialNorm(spNrm);
|
||||
out = where(spNrm == Integer(0), 0.*out, out);
|
||||
for(int i = 0; i < improvement_.size(); i++)
|
||||
{
|
||||
Real f = sqrt(improvement_[i] + 1);
|
||||
out = where(spNrm == Integer(i + 1), f*out, out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::transverseProjectSpatial(GaugeField &out)
|
||||
{
|
||||
const unsigned int nd = grid_->Nd();
|
||||
GaugeLinkField invKHat(grid_), cst(grid_), spdiv(grid_);
|
||||
LatticeInteger spNrm(grid_);
|
||||
std::vector<GaugeLinkField> khat, a(nd, grid_), aProj(nd, grid_);
|
||||
|
||||
invKHat = zero;
|
||||
makeSpatialNorm(spNrm);
|
||||
makeKHat(khat);
|
||||
for (unsigned int mu = 0; mu < nd; ++mu)
|
||||
{
|
||||
a[mu] = peekLorentz(out, mu);
|
||||
if (mu < nd - 1)
|
||||
{
|
||||
invKHat += khat[mu]*conjugate(khat[mu]);
|
||||
}
|
||||
}
|
||||
cst = ScalarComplex(1., 0.);
|
||||
invKHat = where(spNrm == Integer(0), cst, invKHat);
|
||||
invKHat = cst/invKHat;
|
||||
cst = zero;
|
||||
invKHat = where(spNrm == Integer(0), cst, invKHat);
|
||||
spdiv = zero;
|
||||
for (unsigned int nu = 0; nu < nd - 1; ++nu)
|
||||
{
|
||||
spdiv += conjugate(khat[nu])*a[nu];
|
||||
}
|
||||
spdiv *= invKHat;
|
||||
for (unsigned int mu = 0; mu < nd; ++mu)
|
||||
{
|
||||
aProj[mu] = a[mu] - khat[mu]*spdiv;
|
||||
pokeLorentz(out, aProj[mu], mu);
|
||||
}
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::gaugeTransform(GaugeField &out)
|
||||
{
|
||||
switch (gauge_)
|
||||
{
|
||||
case Gauge::feynman:
|
||||
break;
|
||||
case Gauge::coulomb:
|
||||
transverseProjectSpatial(out);
|
||||
break;
|
||||
case Gauge::landau:
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::MomentumSpacePropagator(const GaugeField &in,
|
||||
GaugeField &out)
|
||||
{
|
||||
LatticeComplex momProp(grid_);
|
||||
|
||||
makeInvKHatSquared(momProp);
|
||||
zmSub(momProp);
|
||||
|
||||
out = in*momProp;
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::StochasticWeight(GaugeLinkField &weight)
|
||||
{
|
||||
const unsigned int nd = grid_->Nd();
|
||||
std::vector<int> l = grid_->FullDimensions();
|
||||
Integer vol = 1;
|
||||
|
||||
for(unsigned int mu = 0; mu < nd; mu++)
|
||||
{
|
||||
vol = vol*l[mu];
|
||||
}
|
||||
makeInvKHatSquared(weight);
|
||||
weight = sqrt(vol)*sqrt(weight);
|
||||
zmSub(weight);
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::StochasticField(GaugeField &out, GridParallelRNG &rng)
|
||||
{
|
||||
GaugeLinkField weight(grid_);
|
||||
|
||||
StochasticWeight(weight);
|
||||
StochasticField(out, rng, weight);
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::StochasticField(GaugeField &out, GridParallelRNG &rng,
|
||||
const GaugeLinkField &weight)
|
||||
{
|
||||
const unsigned int nd = grid_->Nd();
|
||||
GaugeLinkField r(grid_);
|
||||
GaugeField aTilde(grid_);
|
||||
FFT fft(dynamic_cast<GridCartesian *>(grid_));
|
||||
|
||||
for(unsigned int mu = 0; mu < nd; mu++)
|
||||
{
|
||||
gaussian(rng, r);
|
||||
r = weight*r;
|
||||
pokeLorentz(aTilde, r, mu);
|
||||
}
|
||||
gaugeTransform(aTilde);
|
||||
fft.FFT_all_dim(out, aTilde, FFT::backward);
|
||||
out = real(out);
|
||||
}
|
||||
|
||||
template<class GImpl>
|
||||
void Photon<GImpl>::UnitField(GaugeField &out)
|
||||
{
|
||||
const unsigned int nd = grid_->Nd();
|
||||
GaugeLinkField r(grid_);
|
||||
|
||||
r = ScalarComplex(1., 0.);
|
||||
for(unsigned int mu = 0; mu < nd; mu++)
|
||||
{
|
||||
pokeLorentz(out, r, mu);
|
||||
}
|
||||
out = real(out);
|
||||
}
|
||||
|
||||
}}
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace Grid{
|
||||
namespace QCD{
|
||||
|
||||
template<class Field>
|
||||
void HighBoundCheck(LinearOperatorBase<Field> &HermOp,
|
||||
Field &Phi,
|
||||
RealD hi)
|
||||
{
|
||||
// Eigenvalue bound check at high end
|
||||
PowerMethod<Field> power_method;
|
||||
auto lambda_max = power_method(HermOp,Phi);
|
||||
std::cout << GridLogMessage << "Pseudofermion action lamda_max "<<lambda_max<<"( bound "<<hi<<")"<<std::endl;
|
||||
assert( (lambda_max < hi) && " High Bounds Check on operator failed" );
|
||||
}
|
||||
|
||||
template<class Field> void InverseSqrtBoundsCheck(int MaxIter,double tol,
|
||||
LinearOperatorBase<Field> &HermOp,
|
||||
Field &GaussNoise,
|
||||
MultiShiftFunction &PowerNegHalf)
|
||||
{
|
||||
GridBase *FermionGrid = GaussNoise._grid;
|
||||
|
||||
Field X(FermionGrid);
|
||||
Field Y(FermionGrid);
|
||||
Field Z(FermionGrid);
|
||||
|
||||
X=GaussNoise;
|
||||
RealD Nx = norm2(X);
|
||||
|
||||
ConjugateGradientMultiShift<Field> msCG(MaxIter,PowerNegHalf);
|
||||
msCG(HermOp,X,Y);
|
||||
msCG(HermOp,Y,Z);
|
||||
|
||||
RealD Nz = norm2(Z);
|
||||
|
||||
HermOp.HermOp(Z,Y);
|
||||
RealD Ny = norm2(Y);
|
||||
|
||||
X=X-Y;
|
||||
RealD Nd = norm2(X);
|
||||
std::cout << "************************* "<<std::endl;
|
||||
std::cout << " noise = "<<Nx<<std::endl;
|
||||
std::cout << " (MdagM^-1/2)^2 noise = "<<Nz<<std::endl;
|
||||
std::cout << " MdagM (MdagM^-1/2)^2 noise = "<<Ny<<std::endl;
|
||||
std::cout << " noise - MdagM (MdagM^-1/2)^2 noise = "<<Nd<<std::endl;
|
||||
std::cout << "************************* "<<std::endl;
|
||||
assert( (std::sqrt(Nd/Nx)<tol) && " InverseSqrtBoundsCheck ");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/qcd/action/scalar/CovariantLaplacian.h
|
||||
|
||||
Copyright (C) 2016
|
||||
|
||||
Author: Azusa Yamaguchi
|
||||
|
||||
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
|
||||
*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
template <class Gimpl> class CovariantSmearing : public Gimpl
|
||||
{
|
||||
public:
|
||||
INHERIT_GIMPL_TYPES(Gimpl);
|
||||
|
||||
typedef typename Gimpl::GaugeLinkField GaugeMat;
|
||||
typedef typename Gimpl::GaugeField GaugeLorentz;
|
||||
|
||||
template<typename T>
|
||||
static void GaussianSmear(const std::vector<LatticeColourMatrix>& U,
|
||||
T& chi,
|
||||
const Real& width, int Iterations, int orthog)
|
||||
{
|
||||
GridBase *grid = chi._grid;
|
||||
T psi(grid);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Follow Chroma conventions for width to keep compatibility with previous data
|
||||
// Free field iterates
|
||||
// chi = (1 - w^2/4N p^2)^N chi
|
||||
//
|
||||
// ~ (e^(-w^2/4N p^2)^N chi
|
||||
// ~ (e^(-w^2/4 p^2) chi
|
||||
// ~ (e^(-w'^2/2 p^2) chi [ w' = w/sqrt(2) ]
|
||||
//
|
||||
// Which in coordinate space is proportional to
|
||||
//
|
||||
// e^(-x^2/w^2) = e^(-x^2/2w'^2)
|
||||
//
|
||||
// The 4 is a bit unconventional from Gaussian width perspective, but... it's Chroma convention.
|
||||
// 2nd derivative approx d^2/dx^2 = x+mu + x-mu - 2x
|
||||
//
|
||||
// d^2/dx^2 = - p^2
|
||||
//
|
||||
// chi = ( 1 + w^2/4N d^2/dx^2 )^N chi
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
Real coeff = (width*width) / Real(4*Iterations);
|
||||
|
||||
int dims = Nd;
|
||||
if( orthog < Nd ) dims=Nd-1;
|
||||
|
||||
for(int n = 0; n < Iterations; ++n) {
|
||||
psi = (-2.0*dims)*chi;
|
||||
for(int mu=0;mu<Nd;mu++) {
|
||||
if ( mu != orthog ) {
|
||||
psi = psi + Gimpl::CovShiftForward(U[mu],mu,chi);
|
||||
psi = psi + Gimpl::CovShiftBackward(U[mu],mu,chi);
|
||||
}
|
||||
}
|
||||
chi = chi + coeff*psi;
|
||||
}
|
||||
}
|
||||
};
|
||||
}}
|
@ -1,660 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/BaseIO.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_ABSTRACT_READER_H
|
||||
#define GRID_SERIALISATION_ABSTRACT_READER_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <Grid/tensors/Tensors.h>
|
||||
#include <Grid/serialisation/VectorUtils.h>
|
||||
#include <Grid/Eigen/unsupported/CXX11/Tensor>
|
||||
|
||||
namespace Grid {
|
||||
namespace EigenIO {
|
||||
// EigenIO works for scalars that are not just Grid supported scalars
|
||||
template<typename T, typename V = void> struct is_complex : public std::false_type {};
|
||||
// Support all complex types (not just Grid complex types) - even if the definitions overlap (!)
|
||||
template<typename T> struct is_complex< T , typename
|
||||
std::enable_if< ::Grid::is_complex< T >::value>::type> : public std::true_type {};
|
||||
template<typename T> struct is_complex<std::complex<T>, typename
|
||||
std::enable_if<!::Grid::is_complex<std::complex<T>>::value>::type> : public std::true_type {};
|
||||
|
||||
// Helpers to support I/O for Eigen tensors of arithmetic scalars, complex types, or Grid tensors
|
||||
template<typename T, typename V = void> struct is_scalar : public std::false_type {};
|
||||
template<typename T> struct is_scalar<T, typename std::enable_if<std::is_arithmetic<T>::value || is_complex<T>::value>::type> : public std::true_type {};
|
||||
|
||||
// Is this an Eigen tensor
|
||||
template<typename T> struct is_tensor : std::integral_constant<bool,
|
||||
std::is_base_of<Eigen::TensorBase<T, Eigen::ReadOnlyAccessors>, T>::value> {};
|
||||
|
||||
// Is this an Eigen tensor of a supported scalar
|
||||
template<typename T, typename V = void> struct is_tensor_of_scalar : public std::false_type {};
|
||||
template<typename T> struct is_tensor_of_scalar<T, typename std::enable_if<is_tensor<T>::value && is_scalar<typename T::Scalar>::value>::type> : public std::true_type {};
|
||||
|
||||
// Is this an Eigen tensor of a supported container
|
||||
template<typename T, typename V = void> struct is_tensor_of_container : public std::false_type {};
|
||||
template<typename T> struct is_tensor_of_container<T, typename std::enable_if<is_tensor<T>::value && isGridTensor<typename T::Scalar>::value>::type> : public std::true_type {};
|
||||
|
||||
// These traits describe the scalars inside Eigen tensors
|
||||
// I wish I could define these in reference to the scalar type (so there would be fewer traits defined)
|
||||
// but I'm unable to find a syntax to make this work
|
||||
template<typename T, typename V = void> struct Traits {};
|
||||
// Traits are the default for scalars, or come from GridTypeMapper for GridTensors
|
||||
template<typename T> struct Traits<T, typename std::enable_if<is_tensor_of_scalar<T>::value>::type>
|
||||
: public GridTypeMapper_Base {
|
||||
using scalar_type = typename T::Scalar; // ultimate base scalar
|
||||
static constexpr bool is_complex = ::Grid::EigenIO::is_complex<scalar_type>::value;
|
||||
};
|
||||
// Traits are the default for scalars, or come from GridTypeMapper for GridTensors
|
||||
template<typename T> struct Traits<T, typename std::enable_if<is_tensor_of_container<T>::value>::type> {
|
||||
using BaseTraits = GridTypeMapper<typename T::Scalar>;
|
||||
using scalar_type = typename BaseTraits::scalar_type; // ultimate base scalar
|
||||
static constexpr bool is_complex = ::Grid::EigenIO::is_complex<scalar_type>::value;
|
||||
static constexpr int TensorLevel = BaseTraits::TensorLevel;
|
||||
static constexpr int Rank = BaseTraits::Rank;
|
||||
static constexpr std::size_t count = BaseTraits::count;
|
||||
static constexpr int Dimension(int dim) { return BaseTraits::Dimension(dim); }
|
||||
};
|
||||
|
||||
// Is this a fixed-size Eigen tensor
|
||||
template<typename T> struct is_tensor_fixed : public std::false_type {};
|
||||
template<typename Scalar_, typename Dimensions_, int Options_, typename IndexType>
|
||||
struct is_tensor_fixed<Eigen::TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType>>
|
||||
: public std::true_type {};
|
||||
template<typename Scalar_, typename Dimensions_, int Options_, typename IndexType,
|
||||
int MapOptions_, template <class> class MapPointer_>
|
||||
struct is_tensor_fixed<Eigen::TensorMap<Eigen::TensorFixedSize<Scalar_, Dimensions_,
|
||||
Options_, IndexType>, MapOptions_, MapPointer_>>
|
||||
: public std::true_type {};
|
||||
|
||||
// Is this a variable-size Eigen tensor
|
||||
template<typename T, typename V = void> struct is_tensor_variable : public std::false_type {};
|
||||
template<typename T> struct is_tensor_variable<T, typename std::enable_if<is_tensor<T>::value
|
||||
&& !is_tensor_fixed<T>::value>::type> : public std::true_type {};
|
||||
}
|
||||
|
||||
// Abstract writer/reader classes ////////////////////////////////////////////
|
||||
// static polymorphism implemented using CRTP idiom
|
||||
class Serializable;
|
||||
|
||||
// Static abstract writer
|
||||
template <typename T>
|
||||
class Writer
|
||||
{
|
||||
public:
|
||||
Writer(void);
|
||||
virtual ~Writer(void) = default;
|
||||
void push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value>::type
|
||||
write(const std::string& s, const U &output);
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value && !EigenIO::is_tensor<U>::value>::type
|
||||
write(const std::string& s, const U &output);
|
||||
template <typename U>
|
||||
void write(const std::string &s, const iScalar<U> &output);
|
||||
template <typename U, int N>
|
||||
void write(const std::string &s, const iVector<U, N> &output);
|
||||
template <typename U, int N>
|
||||
void write(const std::string &s, const iMatrix<U, N> &output);
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value>::type
|
||||
write(const std::string &s, const ETensor &output);
|
||||
|
||||
// Helper functions for Scalar vs Container specialisations
|
||||
template <typename ETensor>
|
||||
inline typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value,
|
||||
const typename ETensor::Scalar *>::type
|
||||
getFirstScalar(const ETensor &output)
|
||||
{
|
||||
return output.data();
|
||||
}
|
||||
|
||||
template <typename ETensor>
|
||||
inline typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value,
|
||||
const typename EigenIO::Traits<ETensor>::scalar_type *>::type
|
||||
getFirstScalar(const ETensor &output)
|
||||
{
|
||||
return output.data()->begin();
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
|
||||
copyScalars(S * &pCopy, const S &Source)
|
||||
{
|
||||
* pCopy ++ = Source;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
inline typename std::enable_if<isGridTensor<S>::value, void>::type
|
||||
copyScalars(typename GridTypeMapper<S>::scalar_type * &pCopy, const S &Source)
|
||||
{
|
||||
for( const typename GridTypeMapper<S>::scalar_type &item : Source )
|
||||
* pCopy ++ = item;
|
||||
}
|
||||
|
||||
void scientificFormat(const bool set);
|
||||
bool isScientific(void);
|
||||
void setPrecision(const unsigned int prec);
|
||||
unsigned int getPrecision(void);
|
||||
private:
|
||||
T *upcast;
|
||||
bool scientific_{false};
|
||||
unsigned int prec_{0};
|
||||
};
|
||||
|
||||
// Static abstract reader
|
||||
template <typename T>
|
||||
class Reader
|
||||
{
|
||||
public:
|
||||
Reader(void);
|
||||
virtual ~Reader(void) = default;
|
||||
bool push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
read(const std::string& s, U &output);
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value
|
||||
&& !EigenIO::is_tensor<U>::value, void>::type
|
||||
read(const std::string& s, U &output);
|
||||
template <typename U>
|
||||
void read(const std::string &s, iScalar<U> &output);
|
||||
template <typename U, int N>
|
||||
void read(const std::string &s, iVector<U, N> &output);
|
||||
template <typename U, int N>
|
||||
void read(const std::string &s, iMatrix<U, N> &output);
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
|
||||
read(const std::string &s, ETensor &output);
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor_fixed<ETensor>::value, void>::type
|
||||
Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims );
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor_variable<ETensor>::value, void>::type
|
||||
Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims );
|
||||
|
||||
// Helper functions for Scalar vs Container specialisations
|
||||
template <typename S>
|
||||
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
|
||||
copyScalars(S &Dest, const S * &pSource)
|
||||
{
|
||||
Dest = * pSource ++;
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
inline typename std::enable_if<isGridTensor<S>::value, void>::type
|
||||
copyScalars(S &Dest, const typename GridTypeMapper<S>::scalar_type * &pSource)
|
||||
{
|
||||
for( typename GridTypeMapper<S>::scalar_type &item : Dest )
|
||||
item = * pSource ++;
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename U>
|
||||
void fromString(U &output, const std::string &s);
|
||||
private:
|
||||
T *upcast;
|
||||
};
|
||||
|
||||
// What is the vtype
|
||||
template<typename T> struct isReader {
|
||||
static const bool value = false;
|
||||
};
|
||||
template<typename T> struct isWriter {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
// Writer template implementation
|
||||
template <typename T>
|
||||
Writer<T>::Writer(void)
|
||||
{
|
||||
upcast = static_cast<T *>(this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::push(const std::string &s)
|
||||
{
|
||||
upcast->push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::pop(void)
|
||||
{
|
||||
upcast->pop();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
Writer<T>::write(const std::string &s, const U &output)
|
||||
{
|
||||
U::write(*this, s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value
|
||||
&& !EigenIO::is_tensor<U>::value, void>::type
|
||||
Writer<T>::write(const std::string &s, const U &output)
|
||||
{
|
||||
upcast->writeDefault(s, output);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Writer<T>::write(const std::string &s, const iScalar<U> &output)
|
||||
{
|
||||
upcast->writeDefault(s, tensorToVec(output));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Writer<T>::write(const std::string &s, const iVector<U, N> &output)
|
||||
{
|
||||
upcast->writeDefault(s, tensorToVec(output));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Writer<T>::write(const std::string &s, const iMatrix<U, N> &output)
|
||||
{
|
||||
upcast->writeDefault(s, tensorToVec(output));
|
||||
}
|
||||
|
||||
// Eigen::Tensors of Grid tensors (iScalar, iVector, iMatrix)
|
||||
template <typename T>
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
|
||||
Writer<T>::write(const std::string &s, const ETensor &output)
|
||||
{
|
||||
using Index = typename ETensor::Index;
|
||||
using Container = typename ETensor::Scalar; // NB: could be same as scalar
|
||||
using Traits = EigenIO::Traits<ETensor>;
|
||||
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
|
||||
constexpr unsigned int TensorRank{ETensor::NumIndices};
|
||||
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
|
||||
constexpr unsigned int TotalRank{TensorRank + ContainerRank};
|
||||
const Index NumElements{output.size()};
|
||||
assert( NumElements > 0 );
|
||||
|
||||
// Get the dimensionality of the tensor
|
||||
std::vector<std::size_t> TotalDims(TotalRank);
|
||||
for(auto i = 0; i < TensorRank; i++ ) {
|
||||
auto dim = output.dimension(i);
|
||||
TotalDims[i] = static_cast<size_t>(dim);
|
||||
assert( TotalDims[i] == dim ); // check we didn't lose anything in the conversion
|
||||
}
|
||||
for(auto i = 0; i < ContainerRank; i++ )
|
||||
TotalDims[TensorRank + i] = Traits::Dimension(i);
|
||||
|
||||
// If the Tensor isn't in Row-Major order, then we'll need to copy it's data
|
||||
const bool CopyData{NumElements > 1 && ETensor::Layout != Eigen::StorageOptions::RowMajor};
|
||||
const Scalar * pWriteBuffer;
|
||||
std::vector<Scalar> CopyBuffer;
|
||||
const Index TotalNumElements = NumElements * Traits::count;
|
||||
if( !CopyData ) {
|
||||
pWriteBuffer = getFirstScalar( output );
|
||||
} else {
|
||||
// Regardless of the Eigen::Tensor storage order, the copy will be Row Major
|
||||
CopyBuffer.resize( TotalNumElements );
|
||||
Scalar * pCopy = &CopyBuffer[0];
|
||||
pWriteBuffer = pCopy;
|
||||
std::array<Index, TensorRank> MyIndex;
|
||||
for( auto &idx : MyIndex ) idx = 0;
|
||||
for( auto n = 0; n < NumElements; n++ ) {
|
||||
const Container & c = output( MyIndex );
|
||||
copyScalars( pCopy, c );
|
||||
// Now increment the index
|
||||
for( int i = output.NumDimensions - 1; i >= 0 && ++MyIndex[i] == output.dimension(i); i-- )
|
||||
MyIndex[i] = 0;
|
||||
}
|
||||
}
|
||||
upcast->template writeMultiDim<Scalar>(s, TotalDims, pWriteBuffer, TotalNumElements);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::scientificFormat(const bool set)
|
||||
{
|
||||
scientific_ = set;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Writer<T>::isScientific(void)
|
||||
{
|
||||
return scientific_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::setPrecision(const unsigned int prec)
|
||||
{
|
||||
prec_ = prec;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned int Writer<T>::getPrecision(void)
|
||||
{
|
||||
return prec_;
|
||||
}
|
||||
|
||||
// Reader template implementation
|
||||
template <typename T>
|
||||
Reader<T>::Reader(void)
|
||||
{
|
||||
upcast = static_cast<T *>(this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Reader<T>::push(const std::string &s)
|
||||
{
|
||||
return upcast->push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Reader<T>::pop(void)
|
||||
{
|
||||
upcast->pop();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
Reader<T>::read(const std::string &s, U &output)
|
||||
{
|
||||
U::read(*this, s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value
|
||||
&& !EigenIO::is_tensor<U>::value, void>::type
|
||||
Reader<T>::read(const std::string &s, U &output)
|
||||
{
|
||||
upcast->readDefault(s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Reader<T>::read(const std::string &s, iScalar<U> &output)
|
||||
{
|
||||
typename TensorToVec<iScalar<U>>::type v;
|
||||
|
||||
upcast->readDefault(s, v);
|
||||
vecToTensor(output, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Reader<T>::read(const std::string &s, iVector<U, N> &output)
|
||||
{
|
||||
typename TensorToVec<iVector<U, N>>::type v;
|
||||
|
||||
upcast->readDefault(s, v);
|
||||
vecToTensor(output, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Reader<T>::read(const std::string &s, iMatrix<U, N> &output)
|
||||
{
|
||||
typename TensorToVec<iMatrix<U, N>>::type v;
|
||||
|
||||
upcast->readDefault(s, v);
|
||||
vecToTensor(output, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
|
||||
Reader<T>::read(const std::string &s, ETensor &output)
|
||||
{
|
||||
using Index = typename ETensor::Index;
|
||||
using Container = typename ETensor::Scalar; // NB: could be same as scalar
|
||||
using Traits = EigenIO::Traits<ETensor>;
|
||||
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
|
||||
constexpr unsigned int TensorRank{ETensor::NumIndices};
|
||||
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
|
||||
constexpr unsigned int TotalRank{TensorRank + ContainerRank};
|
||||
using ETDims = std::array<Index, TensorRank>; // Dimensions of the tensor
|
||||
|
||||
// read the (flat) data and dimensionality
|
||||
std::vector<std::size_t> dimData;
|
||||
std::vector<Scalar> buf;
|
||||
upcast->readMultiDim( s, buf, dimData );
|
||||
assert(dimData.size() == TotalRank && "EigenIO: Tensor rank mismatch" );
|
||||
// Make sure that the number of elements read matches dimensions read
|
||||
std::size_t NumContainers = 1;
|
||||
for( auto i = 0 ; i < TensorRank ; i++ )
|
||||
NumContainers *= dimData[i];
|
||||
// If our scalar object is a Container, make sure it's dimensions match what we read back
|
||||
std::size_t ElementsPerContainer = 1;
|
||||
for( auto i = 0 ; i < ContainerRank ; i++ ) {
|
||||
assert( dimData[TensorRank+i] == Traits::Dimension(i) && "Tensor Container dimensions don't match data" );
|
||||
ElementsPerContainer *= dimData[TensorRank+i];
|
||||
}
|
||||
assert( NumContainers * ElementsPerContainer == buf.size() && "EigenIO: Number of elements != product of dimensions" );
|
||||
// Now see whether the tensor is the right shape, or can be made to be
|
||||
const auto & dims = output.dimensions();
|
||||
bool bShapeOK = (output.data() != nullptr);
|
||||
for( auto i = 0; bShapeOK && i < TensorRank ; i++ )
|
||||
if( dims[i] != dimData[i] )
|
||||
bShapeOK = false;
|
||||
// Make the tensor the same size as the data read
|
||||
ETDims MyIndex;
|
||||
if( !bShapeOK ) {
|
||||
for( auto i = 0 ; i < TensorRank ; i++ )
|
||||
MyIndex[i] = dimData[i];
|
||||
Reshape(output, MyIndex);
|
||||
}
|
||||
// Copy the data into the tensor
|
||||
for( auto &d : MyIndex ) d = 0;
|
||||
const Scalar * pSource = &buf[0];
|
||||
for( std::size_t n = 0 ; n < NumContainers ; n++ ) {
|
||||
Container & c = output( MyIndex );
|
||||
copyScalars( c, pSource );
|
||||
// Now increment the index
|
||||
for( int i = TensorRank - 1; i != -1 && ++MyIndex[i] == dims[i]; i-- )
|
||||
MyIndex[i] = 0;
|
||||
}
|
||||
assert( pSource == &buf[NumContainers * ElementsPerContainer] );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor_fixed<ETensor>::value, void>::type
|
||||
Reader<T>::Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims )
|
||||
{
|
||||
assert( 0 && "EigenIO: Fixed tensor dimensions can't be changed" );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename ETensor>
|
||||
typename std::enable_if<EigenIO::is_tensor_variable<ETensor>::value, void>::type
|
||||
Reader<T>::Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims )
|
||||
{
|
||||
//t.reshape( dims );
|
||||
t.resize( dims );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Reader<T>::fromString(U &output, const std::string &s)
|
||||
{
|
||||
std::istringstream is(s);
|
||||
|
||||
is.exceptions(std::ios::failbit);
|
||||
try
|
||||
{
|
||||
is >> std::boolalpha >> output;
|
||||
}
|
||||
catch(std::ios_base::failure &e)
|
||||
{
|
||||
std::cerr << "numerical conversion failure on '" << s << "' ";
|
||||
std::cerr << "(typeid: " << typeid(U).name() << ")" << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// serializable base class ///////////////////////////////////////////////////
|
||||
class Serializable
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
static inline void write(Writer<T> &WR,const std::string &s,
|
||||
const Serializable &obj)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
static inline void read(Reader<T> &RD,const std::string &s,
|
||||
Serializable &obj)
|
||||
{}
|
||||
|
||||
friend inline std::ostream & operator<<(std::ostream &os,
|
||||
const Serializable &obj)
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static inline typename std::enable_if<!EigenIO::is_tensor<T1>::value || !EigenIO::is_tensor<T2>::value, bool>::type
|
||||
CompareMember(const T1 &lhs, const T2 &rhs) {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static inline typename std::enable_if<EigenIO::is_tensor<T1>::value && EigenIO::is_tensor<T2>::value, bool>::type
|
||||
CompareMember(const T1 &lhs, const T2 &rhs) {
|
||||
// First check whether dimensions match (Eigen tensor library will assert if they don't match)
|
||||
bool bReturnValue = (T1::NumIndices == T2::NumIndices);
|
||||
for( auto i = 0 ; bReturnValue && i < T1::NumIndices ; i++ )
|
||||
bReturnValue = ( lhs.dimension(i) == rhs.dimension(i) );
|
||||
if( bReturnValue ) {
|
||||
Eigen::Tensor<bool, 0, T1::Options> bResult = (lhs == rhs).all();
|
||||
bReturnValue = bResult(0);
|
||||
}
|
||||
return bReturnValue;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline typename std::enable_if<EigenIO::is_tensor<T>::value, bool>::type
|
||||
CompareMember(const std::vector<T> &lhs, const std::vector<T> &rhs) {
|
||||
const auto NumElements = lhs.size();
|
||||
bool bResult = ( NumElements == rhs.size() );
|
||||
for( auto i = 0 ; i < NumElements && bResult ; i++ )
|
||||
bResult = CompareMember(lhs[i], rhs[i]);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline typename std::enable_if<!EigenIO::is_tensor<T>::value, void>::type
|
||||
WriteMember(std::ostream &os, const T &object) {
|
||||
os << object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline typename std::enable_if<EigenIO::is_tensor<T>::value, void>::type
|
||||
WriteMember(std::ostream &os, const T &object) {
|
||||
using Index = typename T::Index;
|
||||
const Index NumElements{object.size()};
|
||||
assert( NumElements > 0 );
|
||||
Index count = 1;
|
||||
os << "T<";
|
||||
for( int i = 0; i < T::NumIndices; i++ ) {
|
||||
Index dim = object.dimension(i);
|
||||
count *= dim;
|
||||
if( i )
|
||||
os << ",";
|
||||
os << dim;
|
||||
}
|
||||
assert( count == NumElements && "Number of elements doesn't match tensor dimensions" );
|
||||
os << ">{";
|
||||
const typename T::Scalar * p = object.data();
|
||||
for( Index i = 0; i < count; i++ ) {
|
||||
if( i )
|
||||
os << ",";
|
||||
os << *p++;
|
||||
}
|
||||
os << "}";
|
||||
}
|
||||
};
|
||||
|
||||
// Generic writer interface //////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline void push(Writer<T> &w, const std::string &s) {
|
||||
w.push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void push(Writer<T> &w, const char *s)
|
||||
{
|
||||
w.push(std::string(s));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void pop(Writer<T> &w)
|
||||
{
|
||||
w.pop();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void write(Writer<T> &w, const std::string& s, const U &output)
|
||||
{
|
||||
w.write(s, output);
|
||||
}
|
||||
|
||||
// Generic reader interface //////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline bool push(Reader<T> &r, const std::string &s)
|
||||
{
|
||||
return r.push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool push(Reader<T> &r, const char *s)
|
||||
{
|
||||
return r.push(std::string(s));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void pop(Reader<T> &r)
|
||||
{
|
||||
r.pop();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void read(Reader<T> &r, const std::string &s, U &output)
|
||||
{
|
||||
r.read(s, output);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,99 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/util/Sha.h
|
||||
|
||||
Copyright (C) 2018
|
||||
|
||||
Author: Peter Boyle
|
||||
|
||||
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 */
|
||||
extern "C" {
|
||||
#include <openssl/sha.h>
|
||||
}
|
||||
#ifdef USE_IPP
|
||||
#include "ipp.h"
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
class GridChecksum
|
||||
{
|
||||
public:
|
||||
static inline uint32_t crc32(const void *data, size_t bytes)
|
||||
{
|
||||
return ::crc32(0L,(unsigned char *)data,bytes);
|
||||
}
|
||||
|
||||
#ifdef USE_IPP
|
||||
static inline uint32_t crc32c(const void* data, size_t bytes)
|
||||
{
|
||||
uint32_t crc32c = ~(uint32_t)0;
|
||||
ippsCRC32C_8u(reinterpret_cast<const unsigned char *>(data), bytes, &crc32c);
|
||||
ippsSwapBytes_32u_I(&crc32c, 1);
|
||||
|
||||
return ~crc32c;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
static inline std::string sha256_string(const std::vector<T> &hash)
|
||||
{
|
||||
std::stringstream sha;
|
||||
std::string s;
|
||||
|
||||
for(unsigned int i = 0; i < hash.size(); i++)
|
||||
{
|
||||
sha << std::hex << static_cast<unsigned int>(hash[i]);
|
||||
}
|
||||
s = sha.str();
|
||||
|
||||
return s;
|
||||
}
|
||||
static inline std::vector<unsigned char> sha256(const void *data,size_t bytes)
|
||||
{
|
||||
std::vector<unsigned char> hash(SHA256_DIGEST_LENGTH);
|
||||
SHA256_CTX sha256;
|
||||
SHA256_Init (&sha256);
|
||||
SHA256_Update(&sha256, data,bytes);
|
||||
SHA256_Final (&hash[0], &sha256);
|
||||
return hash;
|
||||
}
|
||||
static inline std::vector<int> sha256_seeds(const std::string &s)
|
||||
{
|
||||
std::vector<int> seeds;
|
||||
std::vector<unsigned char> uchars = sha256((void *)s.c_str(),s.size());
|
||||
for(int i=0;i<uchars.size();i++) seeds.push_back(uchars[i]);
|
||||
return seeds;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
std::string s("The quick brown fox jumps over the lazy dog");
|
||||
auto csum = GridChecksum::sha256_seeds(s);
|
||||
std::cout << "SHA256 sum is 0x";
|
||||
for(int i=0;i<csum.size;i++) {
|
||||
std::cout << std::hex << csum[i];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
*/
|
@ -1,6 +0,0 @@
|
||||
SUBDIRS = .
|
||||
|
||||
include Make.inc
|
||||
|
||||
|
||||
|
@ -1,198 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/Test_hmc_EODWFRatio.cc
|
||||
|
||||
Copyright (C) 2015-2016
|
||||
|
||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution
|
||||
directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
Grid_init(&argc, &argv);
|
||||
int threads = GridThread::GetThreads();
|
||||
// here make a routine to print all the relevant information on the run
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Typedefs to simplify notation
|
||||
typedef WilsonImplR FermionImplPolicy;
|
||||
typedef MobiusFermionR FermionAction;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
|
||||
typedef Grid::XmlReader Serialiser;
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
IntegratorParameters MD;
|
||||
// typedef GenericHMCRunner<LeapFrog> HMCWrapper;
|
||||
// MD.name = std::string("Leap Frog");
|
||||
// typedef GenericHMCRunner<ForceGradient> HMCWrapper;
|
||||
// MD.name = std::string("Force Gradient");
|
||||
typedef GenericHMCRunner<MinimumNorm2> HMCWrapper;
|
||||
MD.name = std::string("MinimumNorm2");
|
||||
MD.MDsteps = 20;
|
||||
MD.trajL = 1.0;
|
||||
|
||||
HMCparameters HMCparams;
|
||||
HMCparams.StartTrajectory = 0;
|
||||
HMCparams.Trajectories = 200;
|
||||
HMCparams.NoMetropolisUntil= 20;
|
||||
// "[HotStart, ColdStart, TepidStart, CheckpointStart]\n";
|
||||
HMCparams.StartingType =std::string("ColdStart");
|
||||
HMCparams.MD = MD;
|
||||
HMCWrapper TheHMC(HMCparams);
|
||||
|
||||
// Grid from the command line arguments --grid and --mpi
|
||||
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
|
||||
|
||||
CheckpointerParameters CPparams;
|
||||
CPparams.config_prefix = "ckpoint_EODWF_lat";
|
||||
CPparams.rng_prefix = "ckpoint_EODWF_rng";
|
||||
CPparams.saveInterval = 10;
|
||||
CPparams.format = "IEEE64BIG";
|
||||
TheHMC.Resources.LoadNerscCheckpointer(CPparams);
|
||||
|
||||
RNGModuleParameters RNGpar;
|
||||
RNGpar.serial_seeds = "1 2 3 4 5";
|
||||
RNGpar.parallel_seeds = "6 7 8 9 10";
|
||||
TheHMC.Resources.SetRNGSeeds(RNGpar);
|
||||
|
||||
// Construct observables
|
||||
// here there is too much indirection
|
||||
typedef PlaquetteMod<HMCWrapper::ImplPolicy> PlaqObs;
|
||||
TheHMC.Resources.AddObservable<PlaqObs>();
|
||||
//////////////////////////////////////////////
|
||||
|
||||
const int Ls = 16;
|
||||
Real beta = 2.13;
|
||||
Real light_mass = 0.01;
|
||||
Real strange_mass = 0.04;
|
||||
Real pv_mass = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
RealD b = 1.0; // Scale factor two
|
||||
RealD c = 0.0;
|
||||
|
||||
OneFlavourRationalParams OFRp;
|
||||
OFRp.lo = 1.0e-2;
|
||||
OFRp.hi = 64;
|
||||
OFRp.MaxIter = 10000;
|
||||
OFRp.tolerance= 1.0e-10;
|
||||
OFRp.degree = 14;
|
||||
OFRp.precision= 40;
|
||||
|
||||
std::vector<Real> hasenbusch({ 0.1 });
|
||||
|
||||
auto GridPtr = TheHMC.Resources.GetCartesian();
|
||||
auto GridRBPtr = TheHMC.Resources.GetRBCartesian();
|
||||
auto FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtr);
|
||||
auto FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtr);
|
||||
|
||||
IwasakiGaugeActionR GaugeAction(beta);
|
||||
|
||||
// temporarily need a gauge field
|
||||
LatticeGaugeField U(GridPtr);
|
||||
|
||||
// These lines are unecessary if BC are all periodic
|
||||
std::vector<Complex> boundary = {1,1,1,-1};
|
||||
FermionAction::ImplParams Params(boundary);
|
||||
|
||||
double StoppingCondition = 1e-10;
|
||||
double MaxCGIterations = 30000;
|
||||
ConjugateGradient<FermionField> CG(StoppingCondition,MaxCGIterations);
|
||||
|
||||
////////////////////////////////////
|
||||
// Collect actions
|
||||
////////////////////////////////////
|
||||
ActionLevel<HMCWrapper::Field> Level1(1);
|
||||
ActionLevel<HMCWrapper::Field> Level2(4);
|
||||
|
||||
////////////////////////////////////
|
||||
// Strange action
|
||||
////////////////////////////////////
|
||||
|
||||
// FermionAction StrangeOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_mass,M5,b,c, Params);
|
||||
// DomainWallEOFAFermionR Strange_Op_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5);
|
||||
// DomainWallEOFAFermionR Strange_Op_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5);
|
||||
// ExactOneFlavourRatioPseudoFermionAction EOFA(Strange_Op_L,Strange_Op_R,CG,ofp, false);
|
||||
|
||||
FermionAction StrangeOp (U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,strange_mass,M5,b,c, Params);
|
||||
FermionAction StrangePauliVillarsOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,pv_mass, M5,b,c, Params);
|
||||
|
||||
// OneFlavourEvenOddRatioRationalPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion(StrangePauliVillarsOp,StrangeOp,OFRp);
|
||||
OneFlavourRatioRationalPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion(StrangePauliVillarsOp,StrangeOp,OFRp);
|
||||
// TwoFlavourRationalTesterPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion1F(StrangeOp,OFRp);
|
||||
// TwoFlavourPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion2F(StrangeOp,CG,CG);
|
||||
// Level1.push_back(&StrangePseudoFermion2F);
|
||||
// Level1.push_back(&StrangePseudoFermion);
|
||||
|
||||
////////////////////////////////////
|
||||
// up down action
|
||||
////////////////////////////////////
|
||||
std::vector<Real> light_den;
|
||||
std::vector<Real> light_num;
|
||||
|
||||
int n_hasenbusch = hasenbusch.size();
|
||||
light_den.push_back(light_mass);
|
||||
for(int h=0;h<n_hasenbusch;h++){
|
||||
light_den.push_back(hasenbusch[h]);
|
||||
light_num.push_back(hasenbusch[h]);
|
||||
}
|
||||
light_num.push_back(pv_mass);
|
||||
|
||||
std::vector<FermionAction *> Numerators;
|
||||
std::vector<FermionAction *> Denominators;
|
||||
std::vector<TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy> *> Quotients;
|
||||
|
||||
for(int h=0;h<n_hasenbusch+1;h++){
|
||||
std::cout << GridLogMessage << " 2f quotient Action "<< light_num[h] << " / " << light_den[h]<< std::endl;
|
||||
Numerators.push_back (new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_num[h],M5,b,c, Params));
|
||||
Denominators.push_back(new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_den[h],M5,b,c, Params));
|
||||
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],CG,CG));
|
||||
}
|
||||
|
||||
for(int h=0;h<n_hasenbusch+1;h++){
|
||||
Level1.push_back(Quotients[h]);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Gauge action
|
||||
/////////////////////////////////////////////////////////////
|
||||
Level2.push_back(&GaugeAction);
|
||||
TheHMC.TheAction.push_back(Level1);
|
||||
TheHMC.TheAction.push_back(Level2);
|
||||
std::cout << GridLogMessage << " Action complete "<< std::endl;
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// HMC parameters are serialisable
|
||||
|
||||
std::cout << GridLogMessage << " Running the HMC "<< std::endl;
|
||||
TheHMC.Run(); // no smearing
|
||||
|
||||
Grid_finalize();
|
||||
} // main
|
||||
|
||||
|
||||
|
@ -1,452 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file:
|
||||
|
||||
Copyright (C) 2015-2016
|
||||
|
||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
||||
Author: Guido Cossu
|
||||
Author: David Murphy
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution
|
||||
directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
#ifdef GRID_DEFAULT_PRECISION_DOUBLE
|
||||
#define MIXED_PRECISION
|
||||
#endif
|
||||
|
||||
namespace Grid{
|
||||
namespace QCD{
|
||||
|
||||
/*
|
||||
* Need a plan for gauge field update for mixed precision in HMC (2x speed up)
|
||||
* -- Store the single prec action operator.
|
||||
* -- Clone the gauge field from the operator function argument.
|
||||
* -- Build the mixed precision operator dynamically from the passed operator and single prec clone.
|
||||
*/
|
||||
|
||||
template<class FermionOperatorD, class FermionOperatorF, class SchurOperatorD, class SchurOperatorF>
|
||||
class MixedPrecisionConjugateGradientOperatorFunction : public OperatorFunction<typename FermionOperatorD::FermionField> {
|
||||
public:
|
||||
typedef typename FermionOperatorD::FermionField FieldD;
|
||||
typedef typename FermionOperatorF::FermionField FieldF;
|
||||
|
||||
RealD Tolerance;
|
||||
RealD InnerTolerance; //Initial tolerance for inner CG. Defaults to Tolerance but can be changed
|
||||
Integer MaxInnerIterations;
|
||||
Integer MaxOuterIterations;
|
||||
GridBase* SinglePrecGrid4; //Grid for single-precision fields
|
||||
GridBase* SinglePrecGrid5; //Grid for single-precision fields
|
||||
RealD OuterLoopNormMult; //Stop the outer loop and move to a final double prec solve when the residual is OuterLoopNormMult * Tolerance
|
||||
|
||||
FermionOperatorF &FermOpF;
|
||||
FermionOperatorD &FermOpD;;
|
||||
SchurOperatorF &LinOpF;
|
||||
SchurOperatorD &LinOpD;
|
||||
|
||||
Integer TotalInnerIterations; //Number of inner CG iterations
|
||||
Integer TotalOuterIterations; //Number of restarts
|
||||
Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step
|
||||
|
||||
MixedPrecisionConjugateGradientOperatorFunction(RealD tol,
|
||||
Integer maxinnerit,
|
||||
Integer maxouterit,
|
||||
GridBase* _sp_grid4,
|
||||
GridBase* _sp_grid5,
|
||||
FermionOperatorF &_FermOpF,
|
||||
FermionOperatorD &_FermOpD,
|
||||
SchurOperatorF &_LinOpF,
|
||||
SchurOperatorD &_LinOpD):
|
||||
LinOpF(_LinOpF),
|
||||
LinOpD(_LinOpD),
|
||||
FermOpF(_FermOpF),
|
||||
FermOpD(_FermOpD),
|
||||
Tolerance(tol),
|
||||
InnerTolerance(tol),
|
||||
MaxInnerIterations(maxinnerit),
|
||||
MaxOuterIterations(maxouterit),
|
||||
SinglePrecGrid4(_sp_grid4),
|
||||
SinglePrecGrid5(_sp_grid5),
|
||||
OuterLoopNormMult(100.)
|
||||
{
|
||||
/* Debugging instances of objects; references are stored
|
||||
std::cout << GridLogMessage << " Mixed precision CG wrapper LinOpF " <<std::hex<< &LinOpF<<std::dec <<std::endl;
|
||||
std::cout << GridLogMessage << " Mixed precision CG wrapper LinOpD " <<std::hex<< &LinOpD<<std::dec <<std::endl;
|
||||
std::cout << GridLogMessage << " Mixed precision CG wrapper FermOpF " <<std::hex<< &FermOpF<<std::dec <<std::endl;
|
||||
std::cout << GridLogMessage << " Mixed precision CG wrapper FermOpD " <<std::hex<< &FermOpD<<std::dec <<std::endl;
|
||||
*/
|
||||
};
|
||||
|
||||
void operator()(LinearOperatorBase<FieldD> &LinOpU, const FieldD &src, FieldD &psi) {
|
||||
|
||||
std::cout << GridLogMessage << " Mixed precision CG wrapper operator() "<<std::endl;
|
||||
|
||||
SchurOperatorD * SchurOpU = static_cast<SchurOperatorD *>(&LinOpU);
|
||||
|
||||
// std::cout << GridLogMessage << " Mixed precision CG wrapper operator() FermOpU " <<std::hex<< &(SchurOpU->_Mat)<<std::dec <<std::endl;
|
||||
// std::cout << GridLogMessage << " Mixed precision CG wrapper operator() FermOpD " <<std::hex<< &(LinOpD._Mat) <<std::dec <<std::endl;
|
||||
// Assumption made in code to extract gauge field
|
||||
// We could avoid storing LinopD reference alltogether ?
|
||||
assert(&(SchurOpU->_Mat)==&(LinOpD._Mat));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Must snarf a single precision copy of the gauge field in Linop_d argument
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
typedef typename FermionOperatorF::GaugeField GaugeFieldF;
|
||||
typedef typename FermionOperatorF::GaugeLinkField GaugeLinkFieldF;
|
||||
typedef typename FermionOperatorD::GaugeField GaugeFieldD;
|
||||
typedef typename FermionOperatorD::GaugeLinkField GaugeLinkFieldD;
|
||||
|
||||
GridBase * GridPtrF = SinglePrecGrid4;
|
||||
GridBase * GridPtrD = FermOpD.Umu._grid;
|
||||
GaugeFieldF U_f (GridPtrF);
|
||||
GaugeLinkFieldF Umu_f(GridPtrF);
|
||||
// std::cout << " Dim gauge field "<<GridPtrF->Nd()<<std::endl; // 4d
|
||||
// std::cout << " Dim gauge field "<<GridPtrD->Nd()<<std::endl; // 4d
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Moving this to a Clone method of fermion operator would allow to duplicate the
|
||||
// physics parameters and decrease gauge field copies
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
GaugeLinkFieldD Umu_d(GridPtrD);
|
||||
for(int mu=0;mu<Nd*2;mu++){
|
||||
Umu_d = PeekIndex<LorentzIndex>(FermOpD.Umu, mu);
|
||||
precisionChange(Umu_f,Umu_d);
|
||||
PokeIndex<LorentzIndex>(FermOpF.Umu, Umu_f, mu);
|
||||
}
|
||||
pickCheckerboard(Even,FermOpF.UmuEven,FermOpF.Umu);
|
||||
pickCheckerboard(Odd ,FermOpF.UmuOdd ,FermOpF.Umu);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Could test to make sure that LinOpF and LinOpD agree to single prec?
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
GridBase *Fgrid = psi._grid;
|
||||
FieldD tmp2(Fgrid);
|
||||
FieldD tmp1(Fgrid);
|
||||
LinOpU.Op(src,tmp1);
|
||||
LinOpD.Op(src,tmp2);
|
||||
std::cout << " Double gauge field "<< norm2(FermOpD.Umu)<<std::endl;
|
||||
std::cout << " Single gauge field "<< norm2(FermOpF.Umu)<<std::endl;
|
||||
std::cout << " Test of operators "<<norm2(tmp1)<<std::endl;
|
||||
std::cout << " Test of operators "<<norm2(tmp2)<<std::endl;
|
||||
tmp1=tmp1-tmp2;
|
||||
std::cout << " Test of operators diff "<<norm2(tmp1)<<std::endl;
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Make a mixed precision conjugate gradient
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
MixedPrecisionConjugateGradient<FieldD,FieldF> MPCG(Tolerance,MaxInnerIterations,MaxOuterIterations,SinglePrecGrid5,LinOpF,LinOpD);
|
||||
std::cout << GridLogMessage << "Calling mixed precision Conjugate Gradient" <<std::endl;
|
||||
MPCG(src,psi);
|
||||
}
|
||||
};
|
||||
}};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
Grid_init(&argc, &argv);
|
||||
int threads = GridThread::GetThreads();
|
||||
// here make a routine to print all the relevant information on the run
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Typedefs to simplify notation
|
||||
typedef WilsonImplR FermionImplPolicy;
|
||||
typedef MobiusFermionR FermionAction;
|
||||
typedef MobiusFermionF FermionActionF;
|
||||
typedef MobiusEOFAFermionR FermionEOFAAction;
|
||||
typedef MobiusEOFAFermionF FermionEOFAActionF;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
typedef typename FermionActionF::FermionField FermionFieldF;
|
||||
|
||||
typedef Grid::XmlReader Serialiser;
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
IntegratorParameters MD;
|
||||
// typedef GenericHMCRunner<LeapFrog> HMCWrapper;
|
||||
// MD.name = std::string("Leap Frog");
|
||||
typedef GenericHMCRunner<ForceGradient> HMCWrapper;
|
||||
MD.name = std::string("Force Gradient");
|
||||
// typedef GenericHMCRunner<MinimumNorm2> HMCWrapper;
|
||||
// MD.name = std::string("MinimumNorm2");
|
||||
MD.MDsteps = 6;
|
||||
MD.trajL = 1.0;
|
||||
|
||||
HMCparameters HMCparams;
|
||||
HMCparams.StartTrajectory = 590;
|
||||
HMCparams.Trajectories = 1000;
|
||||
HMCparams.NoMetropolisUntil= 0;
|
||||
// "[HotStart, ColdStart, TepidStart, CheckpointStart]\n";
|
||||
// HMCparams.StartingType =std::string("ColdStart");
|
||||
HMCparams.StartingType =std::string("CheckpointStart");
|
||||
HMCparams.MD = MD;
|
||||
HMCWrapper TheHMC(HMCparams);
|
||||
|
||||
// Grid from the command line arguments --grid and --mpi
|
||||
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
|
||||
|
||||
CheckpointerParameters CPparams;
|
||||
CPparams.config_prefix = "ckpoint_EODWF_lat";
|
||||
CPparams.rng_prefix = "ckpoint_EODWF_rng";
|
||||
CPparams.saveInterval = 10;
|
||||
CPparams.format = "IEEE64BIG";
|
||||
TheHMC.Resources.LoadNerscCheckpointer(CPparams);
|
||||
|
||||
RNGModuleParameters RNGpar;
|
||||
RNGpar.serial_seeds = "1 2 3 4 5";
|
||||
RNGpar.parallel_seeds = "6 7 8 9 10";
|
||||
TheHMC.Resources.SetRNGSeeds(RNGpar);
|
||||
|
||||
// Construct observables
|
||||
// here there is too much indirection
|
||||
typedef PlaquetteMod<HMCWrapper::ImplPolicy> PlaqObs;
|
||||
TheHMC.Resources.AddObservable<PlaqObs>();
|
||||
//////////////////////////////////////////////
|
||||
|
||||
const int Ls = 16;
|
||||
Real beta = 2.13;
|
||||
Real light_mass = 0.01;
|
||||
Real strange_mass = 0.04;
|
||||
Real pv_mass = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
RealD b = 1.0;
|
||||
RealD c = 0.0;
|
||||
|
||||
std::vector<Real> hasenbusch({ 0.1, 0.3, 0.6 });
|
||||
|
||||
auto GridPtr = TheHMC.Resources.GetCartesian();
|
||||
auto GridRBPtr = TheHMC.Resources.GetRBCartesian();
|
||||
auto FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtr);
|
||||
auto FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtr);
|
||||
|
||||
std::vector<int> latt = GridDefaultLatt();
|
||||
std::vector<int> mpi = GridDefaultMpi();
|
||||
std::vector<int> simdF = GridDefaultSimd(Nd,vComplexF::Nsimd());
|
||||
std::vector<int> simdD = GridDefaultSimd(Nd,vComplexD::Nsimd());
|
||||
auto GridPtrF = SpaceTimeGrid::makeFourDimGrid(latt,simdF,mpi);
|
||||
auto GridRBPtrF = SpaceTimeGrid::makeFourDimRedBlackGrid(GridPtrF);
|
||||
auto FGridF = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtrF);
|
||||
auto FrbGridF = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtrF);
|
||||
|
||||
IwasakiGaugeActionR GaugeAction(beta);
|
||||
|
||||
// temporarily need a gauge field
|
||||
LatticeGaugeField U(GridPtr);
|
||||
LatticeGaugeFieldF UF(GridPtrF);
|
||||
|
||||
// These lines are unecessary if BC are all periodic
|
||||
std::vector<Complex> boundary = {1,1,1,-1};
|
||||
FermionAction::ImplParams Params(boundary);
|
||||
FermionActionF::ImplParams ParamsF(boundary);
|
||||
|
||||
double ActionStoppingCondition = 1e-10;
|
||||
double DerivativeStoppingCondition = 1e-6;
|
||||
double MaxCGIterations = 30000;
|
||||
|
||||
////////////////////////////////////
|
||||
// Collect actions
|
||||
////////////////////////////////////
|
||||
ActionLevel<HMCWrapper::Field> Level1(1);
|
||||
ActionLevel<HMCWrapper::Field> Level2(8);
|
||||
|
||||
////////////////////////////////////
|
||||
// Strange action
|
||||
////////////////////////////////////
|
||||
typedef SchurDiagMooeeOperator<FermionActionF,FermionFieldF> LinearOperatorF;
|
||||
typedef SchurDiagMooeeOperator<FermionAction ,FermionField > LinearOperatorD;
|
||||
typedef SchurDiagMooeeOperator<FermionEOFAActionF,FermionFieldF> LinearOperatorEOFAF;
|
||||
typedef SchurDiagMooeeOperator<FermionEOFAAction ,FermionField > LinearOperatorEOFAD;
|
||||
|
||||
typedef MixedPrecisionConjugateGradientOperatorFunction<MobiusFermionD,MobiusFermionF,LinearOperatorD,LinearOperatorF> MxPCG;
|
||||
typedef MixedPrecisionConjugateGradientOperatorFunction<MobiusEOFAFermionD,MobiusEOFAFermionF,LinearOperatorEOFAD,LinearOperatorEOFAF> MxPCG_EOFA;
|
||||
|
||||
// DJM: setup for EOFA ratio (Mobius)
|
||||
OneFlavourRationalParams OFRp;
|
||||
OFRp.lo = 0.1;
|
||||
OFRp.hi = 25.0;
|
||||
OFRp.MaxIter = 10000;
|
||||
OFRp.tolerance= 1.0e-9;
|
||||
OFRp.degree = 14;
|
||||
OFRp.precision= 50;
|
||||
|
||||
|
||||
MobiusEOFAFermionR Strange_Op_L (U , *FGrid , *FrbGrid , *GridPtr , *GridRBPtr , strange_mass, strange_mass, pv_mass, 0.0, -1, M5, b, c);
|
||||
MobiusEOFAFermionF Strange_Op_LF(UF, *FGridF, *FrbGridF, *GridPtrF, *GridRBPtrF, strange_mass, strange_mass, pv_mass, 0.0, -1, M5, b, c);
|
||||
MobiusEOFAFermionR Strange_Op_R (U , *FGrid , *FrbGrid , *GridPtr , *GridRBPtr , pv_mass, strange_mass, pv_mass, -1.0, 1, M5, b, c);
|
||||
MobiusEOFAFermionF Strange_Op_RF(UF, *FGridF, *FrbGridF, *GridPtrF, *GridRBPtrF, pv_mass, strange_mass, pv_mass, -1.0, 1, M5, b, c);
|
||||
|
||||
ConjugateGradient<FermionField> ActionCG(ActionStoppingCondition,MaxCGIterations);
|
||||
ConjugateGradient<FermionField> DerivativeCG(DerivativeStoppingCondition,MaxCGIterations);
|
||||
#ifdef MIXED_PRECISION
|
||||
const int MX_inner = 1000;
|
||||
// Mixed precision EOFA
|
||||
LinearOperatorEOFAD Strange_LinOp_L (Strange_Op_L);
|
||||
LinearOperatorEOFAD Strange_LinOp_R (Strange_Op_R);
|
||||
LinearOperatorEOFAF Strange_LinOp_LF(Strange_Op_LF);
|
||||
LinearOperatorEOFAF Strange_LinOp_RF(Strange_Op_RF);
|
||||
|
||||
MxPCG_EOFA ActionCGL(ActionStoppingCondition,
|
||||
MX_inner,
|
||||
MaxCGIterations,
|
||||
GridPtrF,
|
||||
FrbGridF,
|
||||
Strange_Op_LF,Strange_Op_L,
|
||||
Strange_LinOp_LF,Strange_LinOp_L);
|
||||
|
||||
MxPCG_EOFA DerivativeCGL(DerivativeStoppingCondition,
|
||||
MX_inner,
|
||||
MaxCGIterations,
|
||||
GridPtrF,
|
||||
FrbGridF,
|
||||
Strange_Op_LF,Strange_Op_L,
|
||||
Strange_LinOp_LF,Strange_LinOp_L);
|
||||
|
||||
MxPCG_EOFA ActionCGR(ActionStoppingCondition,
|
||||
MX_inner,
|
||||
MaxCGIterations,
|
||||
GridPtrF,
|
||||
FrbGridF,
|
||||
Strange_Op_RF,Strange_Op_R,
|
||||
Strange_LinOp_RF,Strange_LinOp_R);
|
||||
|
||||
MxPCG_EOFA DerivativeCGR(DerivativeStoppingCondition,
|
||||
MX_inner,
|
||||
MaxCGIterations,
|
||||
GridPtrF,
|
||||
FrbGridF,
|
||||
Strange_Op_RF,Strange_Op_R,
|
||||
Strange_LinOp_RF,Strange_LinOp_R);
|
||||
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy>
|
||||
EOFA(Strange_Op_L, Strange_Op_R,
|
||||
ActionCG,
|
||||
ActionCGL, ActionCGR,
|
||||
DerivativeCGL, DerivativeCGR,
|
||||
OFRp, true);
|
||||
#else
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy>
|
||||
EOFA(Strange_Op_L, Strange_Op_R,
|
||||
ActionCG,
|
||||
ActionCG, ActionCG,
|
||||
DerivativeCG, DerivativeCG,
|
||||
OFRp, true);
|
||||
#endif
|
||||
Level1.push_back(&EOFA);
|
||||
|
||||
////////////////////////////////////
|
||||
// up down action
|
||||
////////////////////////////////////
|
||||
std::vector<Real> light_den;
|
||||
std::vector<Real> light_num;
|
||||
|
||||
int n_hasenbusch = hasenbusch.size();
|
||||
light_den.push_back(light_mass);
|
||||
for(int h=0;h<n_hasenbusch;h++){
|
||||
light_den.push_back(hasenbusch[h]);
|
||||
light_num.push_back(hasenbusch[h]);
|
||||
}
|
||||
light_num.push_back(pv_mass);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Forced to replicate the MxPCG and DenominatorsF etc.. because
|
||||
// there is no convenient way to "Clone" physics params from double op
|
||||
// into single op for any operator pair.
|
||||
// Same issue prevents using MxPCG in the Heatbath step
|
||||
//////////////////////////////////////////////////////////////
|
||||
std::vector<FermionAction *> Numerators;
|
||||
std::vector<FermionAction *> Denominators;
|
||||
std::vector<TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy> *> Quotients;
|
||||
std::vector<MxPCG *> ActionMPCG;
|
||||
std::vector<MxPCG *> MPCG;
|
||||
std::vector<FermionActionF *> DenominatorsF;
|
||||
std::vector<LinearOperatorD *> LinOpD;
|
||||
std::vector<LinearOperatorF *> LinOpF;
|
||||
|
||||
for(int h=0;h<n_hasenbusch+1;h++){
|
||||
|
||||
std::cout << GridLogMessage << " 2f quotient Action "<< light_num[h] << " / " << light_den[h]<< std::endl;
|
||||
|
||||
Numerators.push_back (new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_num[h],M5,b,c, Params));
|
||||
Denominators.push_back(new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_den[h],M5,b,c, Params));
|
||||
|
||||
#ifdef MIXED_PRECISION
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Mixed precision CG for 2f force
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DenominatorsF.push_back(new FermionActionF(UF,*FGridF,*FrbGridF,*GridPtrF,*GridRBPtrF,light_den[h],M5,b,c, ParamsF));
|
||||
LinOpD.push_back(new LinearOperatorD(*Denominators[h]));
|
||||
LinOpF.push_back(new LinearOperatorF(*DenominatorsF[h]));
|
||||
|
||||
MPCG.push_back(new MxPCG(DerivativeStoppingCondition,
|
||||
MX_inner,
|
||||
MaxCGIterations,
|
||||
GridPtrF,
|
||||
FrbGridF,
|
||||
*DenominatorsF[h],*Denominators[h],
|
||||
*LinOpF[h], *LinOpD[h]) );
|
||||
|
||||
ActionMPCG.push_back(new MxPCG(ActionStoppingCondition,
|
||||
MX_inner,
|
||||
MaxCGIterations,
|
||||
GridPtrF,
|
||||
FrbGridF,
|
||||
*DenominatorsF[h],*Denominators[h],
|
||||
*LinOpF[h], *LinOpD[h]) );
|
||||
|
||||
// Heatbath not mixed yet. As inverts numerators not so important as raised mass.
|
||||
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],*MPCG[h],*ActionMPCG[h],ActionCG));
|
||||
#else
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Standard CG for 2f force
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],DerivativeCG,ActionCG));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
for(int h=0;h<n_hasenbusch+1;h++){
|
||||
Level1.push_back(Quotients[h]);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Gauge action
|
||||
/////////////////////////////////////////////////////////////
|
||||
Level2.push_back(&GaugeAction);
|
||||
TheHMC.TheAction.push_back(Level1);
|
||||
TheHMC.TheAction.push_back(Level2);
|
||||
std::cout << GridLogMessage << " Action complete "<< std::endl;
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// HMC parameters are serialisable
|
||||
|
||||
std::cout << GridLogMessage << " Running the HMC "<< std::endl;
|
||||
TheHMC.Run(); // no smearing
|
||||
|
||||
Grid_finalize();
|
||||
} // main
|
||||
|
||||
|
||||
|
@ -1,198 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/Test_hmc_EODWFRatio.cc
|
||||
|
||||
Copyright (C) 2015-2016
|
||||
|
||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution
|
||||
directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
Grid_init(&argc, &argv);
|
||||
int threads = GridThread::GetThreads();
|
||||
// here make a routine to print all the relevant information on the run
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Typedefs to simplify notation
|
||||
typedef WilsonImplR FermionImplPolicy;
|
||||
typedef MobiusFermionR FermionAction;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
|
||||
typedef Grid::XmlReader Serialiser;
|
||||
|
||||
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
IntegratorParameters MD;
|
||||
// typedef GenericHMCRunner<LeapFrog> HMCWrapper;
|
||||
// MD.name = std::string("Leap Frog");
|
||||
// typedef GenericHMCRunner<ForceGradient> HMCWrapper;
|
||||
// MD.name = std::string("Force Gradient");
|
||||
typedef GenericHMCRunner<MinimumNorm2> HMCWrapper;
|
||||
MD.name = std::string("MinimumNorm2");
|
||||
MD.MDsteps = 20;
|
||||
MD.trajL = 1.0;
|
||||
|
||||
HMCparameters HMCparams;
|
||||
HMCparams.StartTrajectory = 30;
|
||||
HMCparams.Trajectories = 200;
|
||||
HMCparams.NoMetropolisUntil= 0;
|
||||
// "[HotStart, ColdStart, TepidStart, CheckpointStart]\n";
|
||||
// HMCparams.StartingType =std::string("ColdStart");
|
||||
HMCparams.StartingType =std::string("CheckpointStart");
|
||||
HMCparams.MD = MD;
|
||||
HMCWrapper TheHMC(HMCparams);
|
||||
|
||||
// Grid from the command line arguments --grid and --mpi
|
||||
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
|
||||
|
||||
CheckpointerParameters CPparams;
|
||||
CPparams.config_prefix = "ckpoint_EODWF_lat";
|
||||
CPparams.rng_prefix = "ckpoint_EODWF_rng";
|
||||
CPparams.saveInterval = 10;
|
||||
CPparams.format = "IEEE64BIG";
|
||||
TheHMC.Resources.LoadNerscCheckpointer(CPparams);
|
||||
|
||||
RNGModuleParameters RNGpar;
|
||||
RNGpar.serial_seeds = "1 2 3 4 5";
|
||||
RNGpar.parallel_seeds = "6 7 8 9 10";
|
||||
TheHMC.Resources.SetRNGSeeds(RNGpar);
|
||||
|
||||
// Construct observables
|
||||
// here there is too much indirection
|
||||
typedef PlaquetteMod<HMCWrapper::ImplPolicy> PlaqObs;
|
||||
TheHMC.Resources.AddObservable<PlaqObs>();
|
||||
//////////////////////////////////////////////
|
||||
|
||||
const int Ls = 16;
|
||||
Real beta = 2.13;
|
||||
Real light_mass = 0.01;
|
||||
Real strange_mass = 0.04;
|
||||
Real pv_mass = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
RealD b = 1.0;
|
||||
RealD c = 0.0;
|
||||
|
||||
// FIXME:
|
||||
// Same in MC and MD
|
||||
// Need to mix precision too
|
||||
OneFlavourRationalParams OFRp;
|
||||
OFRp.lo = 4.0e-3;
|
||||
OFRp.hi = 30.0;
|
||||
OFRp.MaxIter = 10000;
|
||||
OFRp.tolerance= 1.0e-10;
|
||||
OFRp.degree = 16;
|
||||
OFRp.precision= 50;
|
||||
|
||||
std::vector<Real> hasenbusch({ 0.1 });
|
||||
|
||||
auto GridPtr = TheHMC.Resources.GetCartesian();
|
||||
auto GridRBPtr = TheHMC.Resources.GetRBCartesian();
|
||||
auto FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtr);
|
||||
auto FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtr);
|
||||
|
||||
IwasakiGaugeActionR GaugeAction(beta);
|
||||
|
||||
// temporarily need a gauge field
|
||||
LatticeGaugeField U(GridPtr);
|
||||
|
||||
// These lines are unecessary if BC are all periodic
|
||||
std::vector<Complex> boundary = {1,1,1,-1};
|
||||
FermionAction::ImplParams Params(boundary);
|
||||
|
||||
double StoppingCondition = 1e-10;
|
||||
double MaxCGIterations = 30000;
|
||||
ConjugateGradient<FermionField> CG(StoppingCondition,MaxCGIterations);
|
||||
|
||||
////////////////////////////////////
|
||||
// Collect actions
|
||||
////////////////////////////////////
|
||||
ActionLevel<HMCWrapper::Field> Level1(1);
|
||||
ActionLevel<HMCWrapper::Field> Level2(4);
|
||||
|
||||
////////////////////////////////////
|
||||
// Strange action
|
||||
////////////////////////////////////
|
||||
|
||||
// FermionAction StrangeOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_mass,M5,b,c, Params);
|
||||
// DomainWallEOFAFermionR Strange_Op_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5);
|
||||
// DomainWallEOFAFermionR Strange_Op_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5);
|
||||
// ExactOneFlavourRatioPseudoFermionAction EOFA(Strange_Op_L,Strange_Op_R,CG,ofp, false);
|
||||
|
||||
FermionAction StrangeOp (U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,strange_mass,M5,b,c, Params);
|
||||
FermionAction StrangePauliVillarsOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,pv_mass, M5,b,c, Params);
|
||||
|
||||
OneFlavourEvenOddRatioRationalPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion(StrangePauliVillarsOp,StrangeOp,OFRp);
|
||||
Level1.push_back(&StrangePseudoFermion);
|
||||
|
||||
////////////////////////////////////
|
||||
// up down action
|
||||
////////////////////////////////////
|
||||
std::vector<Real> light_den;
|
||||
std::vector<Real> light_num;
|
||||
|
||||
int n_hasenbusch = hasenbusch.size();
|
||||
light_den.push_back(light_mass);
|
||||
for(int h=0;h<n_hasenbusch;h++){
|
||||
light_den.push_back(hasenbusch[h]);
|
||||
light_num.push_back(hasenbusch[h]);
|
||||
}
|
||||
light_num.push_back(pv_mass);
|
||||
|
||||
std::vector<FermionAction *> Numerators;
|
||||
std::vector<FermionAction *> Denominators;
|
||||
std::vector<TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy> *> Quotients;
|
||||
|
||||
for(int h=0;h<n_hasenbusch+1;h++){
|
||||
std::cout << GridLogMessage << " 2f quotient Action "<< light_num[h] << " / " << light_den[h]<< std::endl;
|
||||
Numerators.push_back (new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_num[h],M5,b,c, Params));
|
||||
Denominators.push_back(new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_den[h],M5,b,c, Params));
|
||||
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],CG,CG));
|
||||
}
|
||||
|
||||
for(int h=0;h<n_hasenbusch+1;h++){
|
||||
Level1.push_back(Quotients[h]);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Gauge action
|
||||
/////////////////////////////////////////////////////////////
|
||||
Level2.push_back(&GaugeAction);
|
||||
TheHMC.TheAction.push_back(Level1);
|
||||
TheHMC.TheAction.push_back(Level2);
|
||||
std::cout << GridLogMessage << " Action complete "<< std::endl;
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// HMC parameters are serialisable
|
||||
|
||||
std::cout << GridLogMessage << " Running the HMC "<< std::endl;
|
||||
TheHMC.Run(); // no smearing
|
||||
|
||||
Grid_finalize();
|
||||
} // main
|
||||
|
||||
|
||||
|
109
HMC/README
109
HMC/README
@ -1,109 +0,0 @@
|
||||
********************************************************************
|
||||
TODO:
|
||||
********************************************************************
|
||||
|
||||
i) Got mixed precision in 2f and EOFA force and action solves.
|
||||
But need mixed precision in the heatbath solve. Best for Fermop to have a "clone" method, to
|
||||
reduce the number of solver and action objects. Needed ideally for the EOFA heatbath.
|
||||
15% perhaps
|
||||
Combine with 2x trajectory length?
|
||||
|
||||
ii) Rational on EOFA HB -- relax order
|
||||
-- Test the approx as per David email
|
||||
|
||||
Resume / roll.sh
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
- 16^3 Currently 10 traj per hour
|
||||
|
||||
- EOFA use a different derivative solver from action solver
|
||||
- EOFA fix Davids hack to the SchurRedBlack guessing
|
||||
|
||||
*** Reduce precision/tolerance in EOFA with second CG param. (10% speed up)
|
||||
*** Force gradient - reduced precision solve for the gradient (4/3x speedup)
|
||||
|
||||
|
||||
*** Need a plan for gauge field update for mixed precision in HMC (2x speed up)
|
||||
-- Store the single prec action operator.
|
||||
-- Clone the gauge field from the operator function argument.
|
||||
-- Build the mixed precision operator dynamically from the passed operator and single prec clone.
|
||||
|
||||
*** Mixed precision CG into EOFA portion
|
||||
*** Further reduce precision in forces to 10^-6 ?
|
||||
|
||||
*** Overall: a 3x or so is still possible => 500s -> 160s and 20 traj per hour on 16^3.
|
||||
|
||||
- Use mixed precision CG in HMC
|
||||
- SchurRedBlack.h: stop use of operator function; use LinearOperator or similar instead.
|
||||
- Or make an OperatorFunction for mixed precision as a wrapper
|
||||
|
||||
********************************************************************
|
||||
* Signed off 2+1f HMC with Hasenbush and strange RHMC 16^3 x 32 DWF Ls=16 Plaquette 0.5883 ish
|
||||
* Signed off 2+1f HMC with Hasenbush and strange EOFA 16^3 x 32 DWF Ls=16 Plaquette 0.5883 ish
|
||||
* Wilson plaquette cross checked against CPS and literature GwilsonFnone
|
||||
********************************************************************
|
||||
|
||||
********************************************************************
|
||||
* RHMC: Timesteps & eigenranges matched from previous CPS 16^3 x 32 runs:
|
||||
********************************************************************
|
||||
|
||||
****
|
||||
Strange (m=0.04) has eigenspan
|
||||
****
|
||||
16^3 done as 1+1+1 with separate PV's.
|
||||
/dirac1/archive/QCDOC/host/QCDDWF/DWF/2+1f/16nt32/IWASAKI/b2.13/ls16/M1_8/ms0.04/mu0.01/rhmc_multitimescale/evol5/work
|
||||
****
|
||||
2+1f 16^3 - [ 4e^-4, 2.42 ] for strange
|
||||
|
||||
****
|
||||
24^3 done as 1+1+1 at strange, and single quotient https://arxiv.org/pdf/0804.0473.pdf Eq 83,
|
||||
****
|
||||
double lambda_low = 4.0000000000000002e-04 <- strange
|
||||
double lambda_low = 1.0000000000000000e-02 <- pauli villars
|
||||
And high = 2.5
|
||||
|
||||
Array bsn_mass[3] = {
|
||||
double bsn_mass[0] = 1.0000000000000000e+00
|
||||
double bsn_mass[1] = 1.0000000000000000e+00
|
||||
double bsn_mass[2] = 1.0000000000000000e+00
|
||||
}
|
||||
Array frm_mass[3] = {
|
||||
double frm_mass[0] = 4.0000000000000001e-02
|
||||
double frm_mass[1] = 4.0000000000000001e-02
|
||||
double frm_mass[2] = 4.0000000000000001e-02
|
||||
}
|
||||
|
||||
***
|
||||
32^3
|
||||
/dirac1/archive/QCDOC/host/QCDDWF/DWF/2+1f/32nt64/IWASAKI/b2.25/ls16/M1_8/ms0.03/mu0.004/evol6/work
|
||||
***
|
||||
Similar det scheme
|
||||
double lambda_low = 4.0000000000000002e-04
|
||||
double lambda_low = 1.0000000000000000e-02
|
||||
|
||||
Array bsn_mass[3] = {
|
||||
double bsn_mass[0] = 1.0000000000000000e+00
|
||||
double bsn_mass[1] = 1.0000000000000000e+00
|
||||
double bsn_mass[2] = 1.0000000000000000e+00
|
||||
}
|
||||
Array frm_mass[3] = {
|
||||
double frm_mass[0] = 3.0000000000000002e-02
|
||||
double frm_mass[1] = 3.0000000000000002e-02
|
||||
double frm_mass[2] = 3.0000000000000002e-02
|
||||
}
|
||||
|
||||
********************************************************************
|
||||
* Grid: Power method bounds check
|
||||
********************************************************************
|
||||
- Finding largest eigenvalue approx 25 not 2.5
|
||||
- Conventions:
|
||||
|
||||
Grid MpcDagMpc based on:
|
||||
|
||||
(Moo-Moe Mee^-1 Meo)^dag(Moo-Moe Mee^-1 Meo)
|
||||
|
||||
- with Moo = 5-M5 = 3.2
|
||||
- CPS use(d) Moo = 1
|
||||
- Eigenrange in Grid is 3.2^2 rescaled so factor of 10 accounted for
|
||||
|
@ -1,746 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/A2AMatrix.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 A2A_Matrix_hpp_
|
||||
#define A2A_Matrix_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/TimerArray.hpp>
|
||||
#include <Grid/Eigen/unsupported/CXX11/Tensor>
|
||||
#ifdef USE_MKL
|
||||
#include "mkl.h"
|
||||
#include "mkl_cblas.h"
|
||||
#endif
|
||||
|
||||
#ifndef HADRONS_A2AM_NAME
|
||||
#define HADRONS_A2AM_NAME "a2aMatrix"
|
||||
#endif
|
||||
|
||||
#ifndef HADRONS_A2AM_IO_TYPE
|
||||
#define HADRONS_A2AM_IO_TYPE ComplexF
|
||||
#endif
|
||||
|
||||
#define HADRONS_A2AM_PARALLEL_IO
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
// general A2A matrix set based on Eigen tensors and Grid-allocated memory
|
||||
// Dimensions:
|
||||
// 0 - ext - external field (momentum, EM field, ...)
|
||||
// 1 - str - spin-color structure
|
||||
// 2 - t - timeslice
|
||||
// 3 - i - left A2A mode index
|
||||
// 4 - j - right A2A mode index
|
||||
template <typename T>
|
||||
using A2AMatrixSet = Eigen::TensorMap<Eigen::Tensor<T, 5, Eigen::RowMajor>>;
|
||||
|
||||
template <typename T>
|
||||
using A2AMatrix = Eigen::Matrix<T, -1, -1, Eigen::RowMajor>;
|
||||
|
||||
template <typename T>
|
||||
using A2AMatrixTr = Eigen::Matrix<T, -1, -1, Eigen::ColMajor>;
|
||||
|
||||
/******************************************************************************
|
||||
* Abstract class for A2A kernels *
|
||||
******************************************************************************/
|
||||
template <typename T, typename Field>
|
||||
class A2AKernel
|
||||
{
|
||||
public:
|
||||
A2AKernel(void) = default;
|
||||
virtual ~A2AKernel(void) = default;
|
||||
virtual void operator()(A2AMatrixSet<T> &m, const Field *left, const Field *right,
|
||||
const unsigned int orthogDim, double &time) = 0;
|
||||
virtual double flops(const unsigned int blockSizei, const unsigned int blockSizej) = 0;
|
||||
virtual double bytes(const unsigned int blockSizei, const unsigned int blockSizej) = 0;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Class to handle A2A matrix block HDF5 I/O *
|
||||
******************************************************************************/
|
||||
template <typename T>
|
||||
class A2AMatrixIo
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
A2AMatrixIo(void) = default;
|
||||
A2AMatrixIo(std::string filename, std::string dataname,
|
||||
const unsigned int nt, const unsigned int ni = 0,
|
||||
const unsigned int nj = 0);
|
||||
// destructor
|
||||
~A2AMatrixIo(void) = default;
|
||||
// access
|
||||
unsigned int getNi(void) const;
|
||||
unsigned int getNj(void) const;
|
||||
unsigned int getNt(void) const;
|
||||
size_t getSize(void) const;
|
||||
// file allocation
|
||||
template <typename MetadataType>
|
||||
void initFile(const MetadataType &d, const unsigned int chunkSize);
|
||||
// block I/O
|
||||
void saveBlock(const T *data, const unsigned int i, const unsigned int j,
|
||||
const unsigned int blockSizei, const unsigned int blockSizej);
|
||||
void saveBlock(const A2AMatrixSet<T> &m, const unsigned int ext, const unsigned int str,
|
||||
const unsigned int i, const unsigned int j);
|
||||
template <template <class> class Vec, typename VecT>
|
||||
void load(Vec<VecT> &v, double *tRead = nullptr);
|
||||
private:
|
||||
std::string filename_{""}, dataname_{""};
|
||||
unsigned int nt_{0}, ni_{0}, nj_{0};
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Wrapper for A2A matrix block computation *
|
||||
******************************************************************************/
|
||||
template <typename T, typename Field, typename MetadataType, typename TIo = T>
|
||||
class A2AMatrixBlockComputation
|
||||
{
|
||||
private:
|
||||
struct IoHelper
|
||||
{
|
||||
A2AMatrixIo<TIo> io;
|
||||
MetadataType md;
|
||||
unsigned int e, s, i, j;
|
||||
};
|
||||
typedef std::function<std::string(const unsigned int, const unsigned int)> FilenameFn;
|
||||
typedef std::function<MetadataType(const unsigned int, const unsigned int)> MetadataFn;
|
||||
public:
|
||||
// constructor
|
||||
A2AMatrixBlockComputation(GridBase *grid,
|
||||
const unsigned int orthogDim,
|
||||
const unsigned int next,
|
||||
const unsigned int nstr,
|
||||
const unsigned int blockSize,
|
||||
const unsigned int cacheBlockSize,
|
||||
TimerArray *tArray = nullptr);
|
||||
// execution
|
||||
void execute(const std::vector<Field> &left,
|
||||
const std::vector<Field> &right,
|
||||
A2AKernel<T, Field> &kernel,
|
||||
const FilenameFn &ionameFn,
|
||||
const FilenameFn &filenameFn,
|
||||
const MetadataFn &metadataFn);
|
||||
private:
|
||||
// I/O handler
|
||||
void saveBlock(const A2AMatrixSet<TIo> &m, IoHelper &h);
|
||||
private:
|
||||
TimerArray *tArray_;
|
||||
GridBase *grid_;
|
||||
unsigned int orthogDim_, nt_, next_, nstr_, blockSize_, cacheBlockSize_;
|
||||
Vector<T> mCache_;
|
||||
Vector<TIo> mBuf_;
|
||||
std::vector<IoHelper> nodeIo_;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* A2A matrix contraction kernels *
|
||||
******************************************************************************/
|
||||
class A2AContraction
|
||||
{
|
||||
public:
|
||||
// accTrMul(acc, a, b): acc += tr(a*b)
|
||||
template <typename C, typename MatLeft, typename MatRight>
|
||||
static inline void accTrMul(C &acc, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
if ((MatLeft::Options == Eigen::RowMajor) and
|
||||
(MatRight::Options == Eigen::ColMajor))
|
||||
{
|
||||
parallel_for (unsigned int r = 0; r < a.rows(); ++r)
|
||||
{
|
||||
C tmp;
|
||||
#ifdef USE_MKL
|
||||
dotuRow(tmp, r, a, b);
|
||||
#else
|
||||
tmp = a.row(r).conjugate().dot(b.col(r));
|
||||
#endif
|
||||
parallel_critical
|
||||
{
|
||||
acc += tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parallel_for (unsigned int c = 0; c < a.cols(); ++c)
|
||||
{
|
||||
C tmp;
|
||||
#ifdef USE_MKL
|
||||
dotuCol(tmp, c, a, b);
|
||||
#else
|
||||
tmp = a.col(c).conjugate().dot(b.row(c));
|
||||
#endif
|
||||
parallel_critical
|
||||
{
|
||||
acc += tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline double accTrMulFlops(const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
double n = a.rows()*a.cols();
|
||||
|
||||
return 8.*n;
|
||||
}
|
||||
|
||||
// mul(res, a, b): res = a*b
|
||||
#ifdef USE_MKL
|
||||
template <template <class, int...> class Mat, int... Opts>
|
||||
static inline void mul(Mat<ComplexD, Opts...> &res,
|
||||
const Mat<ComplexD, Opts...> &a,
|
||||
const Mat<ComplexD, Opts...> &b)
|
||||
{
|
||||
static const ComplexD one(1., 0.), zero(0., 0.);
|
||||
|
||||
if ((res.rows() != a.rows()) or (res.cols() != b.cols()))
|
||||
{
|
||||
res.resize(a.rows(), b.cols());
|
||||
}
|
||||
if (Mat<ComplexD, Opts...>::Options == Eigen::RowMajor)
|
||||
{
|
||||
cblas_zgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a.rows(), b.cols(),
|
||||
a.cols(), &one, a.data(), a.cols(), b.data(), b.cols(), &zero,
|
||||
res.data(), res.cols());
|
||||
}
|
||||
else if (Mat<ComplexD, Opts...>::Options == Eigen::ColMajor)
|
||||
{
|
||||
cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, a.rows(), b.cols(),
|
||||
a.cols(), &one, a.data(), a.rows(), b.data(), b.rows(), &zero,
|
||||
res.data(), res.rows());
|
||||
}
|
||||
}
|
||||
|
||||
template <template <class, int...> class Mat, int... Opts>
|
||||
static inline void mul(Mat<ComplexF, Opts...> &res,
|
||||
const Mat<ComplexF, Opts...> &a,
|
||||
const Mat<ComplexF, Opts...> &b)
|
||||
{
|
||||
static const ComplexF one(1., 0.), zero(0., 0.);
|
||||
|
||||
if ((res.rows() != a.rows()) or (res.cols() != b.cols()))
|
||||
{
|
||||
res.resize(a.rows(), b.cols());
|
||||
}
|
||||
if (Mat<ComplexF, Opts...>::Options == Eigen::RowMajor)
|
||||
{
|
||||
cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a.rows(), b.cols(),
|
||||
a.cols(), &one, a.data(), a.cols(), b.data(), b.cols(), &zero,
|
||||
res.data(), res.cols());
|
||||
}
|
||||
else if (Mat<ComplexF, Opts...>::Options == Eigen::ColMajor)
|
||||
{
|
||||
cblas_cgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, a.rows(), b.cols(),
|
||||
a.cols(), &one, a.data(), a.rows(), b.data(), b.rows(), &zero,
|
||||
res.data(), res.rows());
|
||||
}
|
||||
}
|
||||
#else
|
||||
template <typename Mat>
|
||||
static inline void mul(Mat &res, const Mat &a, const Mat &b)
|
||||
{
|
||||
res = a*b;
|
||||
}
|
||||
#endif
|
||||
template <typename Mat>
|
||||
static inline double mulFlops(const Mat &a, const Mat &b)
|
||||
{
|
||||
double nr = a.rows(), nc = a.cols();
|
||||
|
||||
return nr*nr*(6.*nc + 2.*(nc - 1.));
|
||||
}
|
||||
private:
|
||||
template <typename C, typename MatLeft, typename MatRight>
|
||||
static inline void makeDotRowPt(C * &aPt, unsigned int &aInc, C * &bPt,
|
||||
unsigned int &bInc, const unsigned int aRow,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
if (MatLeft::Options == Eigen::RowMajor)
|
||||
{
|
||||
aPt = a.data() + aRow*a.cols();
|
||||
aInc = 1;
|
||||
}
|
||||
else if (MatLeft::Options == Eigen::ColMajor)
|
||||
{
|
||||
aPt = a.data() + aRow;
|
||||
aInc = a.rows();
|
||||
}
|
||||
if (MatRight::Options == Eigen::RowMajor)
|
||||
{
|
||||
bPt = b.data() + aRow;
|
||||
bInc = b.cols();
|
||||
}
|
||||
else if (MatRight::Options == Eigen::ColMajor)
|
||||
{
|
||||
bPt = b.data() + aRow*b.rows();
|
||||
bInc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_MKL
|
||||
template <typename C, typename MatLeft, typename MatRight>
|
||||
static inline void makeDotColPt(C * &aPt, unsigned int &aInc, C * &bPt,
|
||||
unsigned int &bInc, const unsigned int aCol,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
if (MatLeft::Options == Eigen::RowMajor)
|
||||
{
|
||||
aPt = a.data() + aCol;
|
||||
aInc = a.cols();
|
||||
}
|
||||
else if (MatLeft::Options == Eigen::ColMajor)
|
||||
{
|
||||
aPt = a.data() + aCol*a.rows();
|
||||
aInc = 1;
|
||||
}
|
||||
if (MatRight::Options == Eigen::RowMajor)
|
||||
{
|
||||
bPt = b.data() + aCol*b.cols();
|
||||
bInc = 1;
|
||||
}
|
||||
else if (MatRight::Options == Eigen::ColMajor)
|
||||
{
|
||||
bPt = b.data() + aCol;
|
||||
bInc = b.rows();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline void dotuRow(ComplexF &res, const unsigned int aRow,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
const ComplexF *aPt, *bPt;
|
||||
unsigned int aInc, bInc;
|
||||
|
||||
makeDotRowPt(aPt, aInc, bPt, bInc, aRow, a, b);
|
||||
cblas_cdotu_sub(a.cols(), aPt, aInc, bPt, bInc, &res);
|
||||
}
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline void dotuCol(ComplexF &res, const unsigned int aCol,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
const ComplexF *aPt, *bPt;
|
||||
unsigned int aInc, bInc;
|
||||
|
||||
makeDotColPt(aPt, aInc, bPt, bInc, aCol, a, b);
|
||||
cblas_cdotu_sub(a.rows(), aPt, aInc, bPt, bInc, &res);
|
||||
}
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline void dotuRow(ComplexD &res, const unsigned int aRow,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
const ComplexD *aPt, *bPt;
|
||||
unsigned int aInc, bInc;
|
||||
|
||||
makeDotRowPt(aPt, aInc, bPt, bInc, aRow, a, b);
|
||||
cblas_zdotu_sub(a.cols(), aPt, aInc, bPt, bInc, &res);
|
||||
}
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline void dotuCol(ComplexD &res, const unsigned int aCol,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
const ComplexD *aPt, *bPt;
|
||||
unsigned int aInc, bInc;
|
||||
|
||||
makeDotColPt(aPt, aInc, bPt, bInc, aCol, a, b);
|
||||
cblas_zdotu_sub(a.rows(), aPt, aInc, bPt, bInc, &res);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* A2AMatrixIo template implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
A2AMatrixIo<T>::A2AMatrixIo(std::string filename, std::string dataname,
|
||||
const unsigned int nt, const unsigned int ni,
|
||||
const unsigned int nj)
|
||||
: filename_(filename), dataname_(dataname)
|
||||
, nt_(nt), ni_(ni), nj_(nj)
|
||||
{}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
unsigned int A2AMatrixIo<T>::getNt(void) const
|
||||
{
|
||||
return nt_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned int A2AMatrixIo<T>::getNi(void) const
|
||||
{
|
||||
return ni_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned int A2AMatrixIo<T>::getNj(void) const
|
||||
{
|
||||
return nj_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t A2AMatrixIo<T>::getSize(void) const
|
||||
{
|
||||
return nt_*ni_*nj_*sizeof(T);
|
||||
}
|
||||
|
||||
// file allocation /////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
template <typename MetadataType>
|
||||
void A2AMatrixIo<T>::initFile(const MetadataType &d, const unsigned int chunkSize)
|
||||
{
|
||||
#ifdef HAVE_HDF5
|
||||
std::vector<hsize_t> dim = {static_cast<hsize_t>(nt_),
|
||||
static_cast<hsize_t>(ni_),
|
||||
static_cast<hsize_t>(nj_)},
|
||||
chunk = {static_cast<hsize_t>(nt_),
|
||||
static_cast<hsize_t>(chunkSize),
|
||||
static_cast<hsize_t>(chunkSize)};
|
||||
H5NS::DataSpace dataspace(dim.size(), dim.data());
|
||||
H5NS::DataSet dataset;
|
||||
H5NS::DSetCreatPropList plist;
|
||||
|
||||
// create empty file just with metadata
|
||||
{
|
||||
Hdf5Writer writer(filename_);
|
||||
write(writer, dataname_, d);
|
||||
}
|
||||
|
||||
// create the dataset
|
||||
Hdf5Reader reader(filename_, false);
|
||||
|
||||
push(reader, dataname_);
|
||||
auto &group = reader.getGroup();
|
||||
plist.setChunk(chunk.size(), chunk.data());
|
||||
plist.setFletcher32();
|
||||
dataset = group.createDataSet(HADRONS_A2AM_NAME, Hdf5Type<T>::type(), dataspace, plist);
|
||||
#else
|
||||
HADRONS_ERROR(Implementation, "all-to-all matrix I/O needs HDF5 library");
|
||||
#endif
|
||||
}
|
||||
|
||||
// block I/O ///////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
void A2AMatrixIo<T>::saveBlock(const T *data,
|
||||
const unsigned int i,
|
||||
const unsigned int j,
|
||||
const unsigned int blockSizei,
|
||||
const unsigned int blockSizej)
|
||||
{
|
||||
#ifdef HAVE_HDF5
|
||||
Hdf5Reader reader(filename_, false);
|
||||
std::vector<hsize_t> count = {nt_, blockSizei, blockSizej},
|
||||
offset = {0, static_cast<hsize_t>(i),
|
||||
static_cast<hsize_t>(j)},
|
||||
stride = {1, 1, 1},
|
||||
block = {1, 1, 1};
|
||||
H5NS::DataSpace memspace(count.size(), count.data()), dataspace;
|
||||
H5NS::DataSet dataset;
|
||||
size_t shift;
|
||||
|
||||
push(reader, dataname_);
|
||||
auto &group = reader.getGroup();
|
||||
dataset = group.openDataSet(HADRONS_A2AM_NAME);
|
||||
dataspace = dataset.getSpace();
|
||||
dataspace.selectHyperslab(H5S_SELECT_SET, count.data(), offset.data(),
|
||||
stride.data(), block.data());
|
||||
dataset.write(data, Hdf5Type<T>::type(), memspace, dataspace);
|
||||
#else
|
||||
HADRONS_ERROR(Implementation, "all-to-all matrix I/O needs HDF5 library");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void A2AMatrixIo<T>::saveBlock(const A2AMatrixSet<T> &m,
|
||||
const unsigned int ext, const unsigned int str,
|
||||
const unsigned int i, const unsigned int j)
|
||||
{
|
||||
unsigned int blockSizei = m.dimension(3);
|
||||
unsigned int blockSizej = m.dimension(4);
|
||||
unsigned int nstr = m.dimension(1);
|
||||
size_t offset = (ext*nstr + str)*nt_*blockSizei*blockSizej;
|
||||
|
||||
saveBlock(m.data() + offset, i, j, blockSizei, blockSizej);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <template <class> class Vec, typename VecT>
|
||||
void A2AMatrixIo<T>::load(Vec<VecT> &v, double *tRead)
|
||||
{
|
||||
#ifdef HAVE_HDF5
|
||||
Hdf5Reader reader(filename_);
|
||||
std::vector<hsize_t> hdim;
|
||||
H5NS::DataSet dataset;
|
||||
H5NS::DataSpace dataspace;
|
||||
H5NS::CompType datatype;
|
||||
|
||||
push(reader, dataname_);
|
||||
auto &group = reader.getGroup();
|
||||
dataset = group.openDataSet(HADRONS_A2AM_NAME);
|
||||
datatype = dataset.getCompType();
|
||||
dataspace = dataset.getSpace();
|
||||
hdim.resize(dataspace.getSimpleExtentNdims());
|
||||
dataspace.getSimpleExtentDims(hdim.data());
|
||||
if ((nt_*ni_*nj_ != 0) and
|
||||
((hdim[0] != nt_) or (hdim[1] != ni_) or (hdim[2] != nj_)))
|
||||
{
|
||||
HADRONS_ERROR(Size, "all-to-all matrix size mismatch (got "
|
||||
+ std::to_string(hdim[0]) + "x" + std::to_string(hdim[1]) + "x"
|
||||
+ std::to_string(hdim[2]) + ", expected "
|
||||
+ std::to_string(nt_) + "x" + std::to_string(ni_) + "x"
|
||||
+ std::to_string(nj_));
|
||||
}
|
||||
else if (ni_*nj_ == 0)
|
||||
{
|
||||
if (hdim[0] != nt_)
|
||||
{
|
||||
HADRONS_ERROR(Size, "all-to-all time size mismatch (got "
|
||||
+ std::to_string(hdim[0]) + ", expected "
|
||||
+ std::to_string(nt_) + ")");
|
||||
}
|
||||
ni_ = hdim[1];
|
||||
nj_ = hdim[2];
|
||||
}
|
||||
|
||||
A2AMatrix<T> buf(ni_, nj_);
|
||||
std::vector<hsize_t> count = {1, static_cast<hsize_t>(ni_),
|
||||
static_cast<hsize_t>(nj_)},
|
||||
stride = {1, 1, 1},
|
||||
block = {1, 1, 1},
|
||||
memCount = {static_cast<hsize_t>(ni_),
|
||||
static_cast<hsize_t>(nj_)};
|
||||
H5NS::DataSpace memspace(memCount.size(), memCount.data());
|
||||
|
||||
std::cout << "Loading timeslice";
|
||||
std::cout.flush();
|
||||
*tRead = 0.;
|
||||
for (unsigned int tp1 = nt_; tp1 > 0; --tp1)
|
||||
{
|
||||
unsigned int t = tp1 - 1;
|
||||
std::vector<hsize_t> offset = {static_cast<hsize_t>(t), 0, 0};
|
||||
|
||||
if (t % 10 == 0)
|
||||
{
|
||||
std::cout << " " << t;
|
||||
std::cout.flush();
|
||||
}
|
||||
dataspace.selectHyperslab(H5S_SELECT_SET, count.data(), offset.data(),
|
||||
stride.data(), block.data());
|
||||
if (tRead) *tRead -= usecond();
|
||||
dataset.read(buf.data(), datatype, memspace, dataspace);
|
||||
if (tRead) *tRead += usecond();
|
||||
v[t] = buf.template cast<VecT>();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
#else
|
||||
HADRONS_ERROR(Implementation, "all-to-all matrix I/O needs HDF5 library");
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* A2AMatrixBlockComputation template implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Field, typename MetadataType, typename TIo>
|
||||
A2AMatrixBlockComputation<T, Field, MetadataType, TIo>
|
||||
::A2AMatrixBlockComputation(GridBase *grid,
|
||||
const unsigned int orthogDim,
|
||||
const unsigned int next,
|
||||
const unsigned int nstr,
|
||||
const unsigned int blockSize,
|
||||
const unsigned int cacheBlockSize,
|
||||
TimerArray *tArray)
|
||||
: grid_(grid), nt_(grid->GlobalDimensions()[orthogDim]), orthogDim_(orthogDim)
|
||||
, next_(next), nstr_(nstr), blockSize_(blockSize), cacheBlockSize_(cacheBlockSize)
|
||||
, tArray_(tArray)
|
||||
{
|
||||
mCache_.resize(nt_*next_*nstr_*cacheBlockSize_*cacheBlockSize_);
|
||||
mBuf_.resize(nt_*next_*nstr_*blockSize_*blockSize_);
|
||||
}
|
||||
|
||||
#define START_TIMER(name) if (tArray_) tArray_->startTimer(name)
|
||||
#define STOP_TIMER(name) if (tArray_) tArray_->stopTimer(name)
|
||||
#define GET_TIMER(name) ((tArray_ != nullptr) ? tArray_->getDTimer(name) : 0.)
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Field, typename MetadataType, typename TIo>
|
||||
void A2AMatrixBlockComputation<T, Field, MetadataType, TIo>
|
||||
::execute(const std::vector<Field> &left, const std::vector<Field> &right,
|
||||
A2AKernel<T, Field> &kernel, const FilenameFn &ionameFn,
|
||||
const FilenameFn &filenameFn, const MetadataFn &metadataFn)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// i,j is first loop over blockSize_ factors
|
||||
// ii,jj is second loop over cacheBlockSize_ factors for high perf contractions
|
||||
// iii,jjj are loops within cacheBlock
|
||||
// Total index is sum of these i+ii+iii etc...
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int N_i = left.size();
|
||||
int N_j = right.size();
|
||||
double flops, bytes, t_kernel;
|
||||
double nodes = grid_->NodeCount();
|
||||
|
||||
int NBlock_i = N_i/blockSize_ + (((N_i % blockSize_) != 0) ? 1 : 0);
|
||||
int NBlock_j = N_j/blockSize_ + (((N_j % blockSize_) != 0) ? 1 : 0);
|
||||
|
||||
for(int i=0;i<N_i;i+=blockSize_)
|
||||
for(int j=0;j<N_j;j+=blockSize_)
|
||||
{
|
||||
// Get the W and V vectors for this block^2 set of terms
|
||||
int N_ii = MIN(N_i-i,blockSize_);
|
||||
int N_jj = MIN(N_j-j,blockSize_);
|
||||
A2AMatrixSet<TIo> mBlock(mBuf_.data(), next_, nstr_, nt_, N_ii, N_jj);
|
||||
|
||||
LOG(Message) << "All-to-all matrix block "
|
||||
<< j/blockSize_ + NBlock_j*i/blockSize_ + 1
|
||||
<< "/" << NBlock_i*NBlock_j << " [" << i <<" .. "
|
||||
<< i+N_ii-1 << ", " << j <<" .. " << j+N_jj-1 << "]"
|
||||
<< std::endl;
|
||||
// Series of cache blocked chunks of the contractions within this block
|
||||
flops = 0.0;
|
||||
bytes = 0.0;
|
||||
t_kernel = 0.0;
|
||||
for(int ii=0;ii<N_ii;ii+=cacheBlockSize_)
|
||||
for(int jj=0;jj<N_jj;jj+=cacheBlockSize_)
|
||||
{
|
||||
double t;
|
||||
int N_iii = MIN(N_ii-ii,cacheBlockSize_);
|
||||
int N_jjj = MIN(N_jj-jj,cacheBlockSize_);
|
||||
A2AMatrixSet<T> mCacheBlock(mCache_.data(), next_, nstr_, nt_, N_iii, N_jjj);
|
||||
|
||||
START_TIMER("kernel");
|
||||
kernel(mCacheBlock, &left[i+ii], &right[j+jj], orthogDim_, t);
|
||||
STOP_TIMER("kernel");
|
||||
t_kernel += t;
|
||||
flops += kernel.flops(N_iii, N_jjj);
|
||||
bytes += kernel.bytes(N_iii, N_jjj);
|
||||
|
||||
START_TIMER("cache copy");
|
||||
parallel_for_nest5(int e =0;e<next_;e++)
|
||||
for(int s =0;s< nstr_;s++)
|
||||
for(int t =0;t< nt_;t++)
|
||||
for(int iii=0;iii< N_iii;iii++)
|
||||
for(int jjj=0;jjj< N_jjj;jjj++)
|
||||
{
|
||||
mBlock(e,s,t,ii+iii,jj+jjj) = mCacheBlock(e,s,t,iii,jjj);
|
||||
}
|
||||
STOP_TIMER("cache copy");
|
||||
}
|
||||
|
||||
// perf
|
||||
LOG(Message) << "Kernel perf " << flops/t_kernel/1.0e3/nodes
|
||||
<< " Gflop/s/node " << std::endl;
|
||||
LOG(Message) << "Kernel perf " << bytes/t_kernel*1.0e6/1024/1024/1024/nodes
|
||||
<< " GB/s/node " << std::endl;
|
||||
|
||||
// IO
|
||||
double blockSize, ioTime;
|
||||
unsigned int myRank = grid_->ThisRank(), nRank = grid_->RankCount();
|
||||
|
||||
LOG(Message) << "Writing block to disk" << std::endl;
|
||||
ioTime = -GET_TIMER("IO: write block");
|
||||
START_TIMER("IO: total");
|
||||
makeFileDir(filenameFn(0, 0), grid_);
|
||||
#ifdef HADRONS_A2AM_PARALLEL_IO
|
||||
grid_->Barrier();
|
||||
// make task list for current node
|
||||
nodeIo_.clear();
|
||||
for(int f = myRank; f < next_*nstr_; f += nRank)
|
||||
{
|
||||
IoHelper h;
|
||||
|
||||
h.i = i;
|
||||
h.j = j;
|
||||
h.e = f/nstr_;
|
||||
h.s = f % nstr_;
|
||||
h.io = A2AMatrixIo<TIo>(filenameFn(h.e, h.s),
|
||||
ionameFn(h.e, h.s), nt_, N_i, N_j);
|
||||
h.md = metadataFn(h.e, h.s);
|
||||
nodeIo_.push_back(h);
|
||||
}
|
||||
// parallel IO
|
||||
for (auto &h: nodeIo_)
|
||||
{
|
||||
saveBlock(mBlock, h);
|
||||
}
|
||||
grid_->Barrier();
|
||||
#else
|
||||
// serial IO, for testing purposes only
|
||||
for(int e = 0; e < next_; e++)
|
||||
for(int s = 0; s < nstr_; s++)
|
||||
{
|
||||
IoHelper h;
|
||||
|
||||
h.i = i;
|
||||
h.j = j;
|
||||
h.e = e;
|
||||
h.s = s;
|
||||
h.io = A2AMatrixIo<TIo>(filenameFn(h.e, h.s),
|
||||
ionameFn(h.e, h.s), nt_, N_i, N_j);
|
||||
h.md = metadataFn(h.e, h.s);
|
||||
saveBlock(mfBlock, h);
|
||||
}
|
||||
#endif
|
||||
STOP_TIMER("IO: total");
|
||||
blockSize = static_cast<double>(next_*nstr_*nt_*N_ii*N_jj*sizeof(TIo));
|
||||
ioTime += GET_TIMER("IO: write block");
|
||||
LOG(Message) << "HDF5 IO done " << sizeString(blockSize) << " in "
|
||||
<< ioTime << " us ("
|
||||
<< blockSize/ioTime*1.0e6/1024/1024
|
||||
<< " MB/s)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// I/O handler /////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Field, typename MetadataType, typename TIo>
|
||||
void A2AMatrixBlockComputation<T, Field, MetadataType, TIo>
|
||||
::saveBlock(const A2AMatrixSet<TIo> &m, IoHelper &h)
|
||||
{
|
||||
if ((h.i == 0) and (h.j == 0))
|
||||
{
|
||||
START_TIMER("IO: file creation");
|
||||
h.io.initFile(h.md, blockSize_);
|
||||
STOP_TIMER("IO: file creation");
|
||||
}
|
||||
START_TIMER("IO: write block");
|
||||
h.io.saveBlock(m, h.e, h.s, h.i, h.j);
|
||||
STOP_TIMER("IO: write block");
|
||||
}
|
||||
|
||||
#undef START_TIMER
|
||||
#undef STOP_TIMER
|
||||
#undef GET_TIMER
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // A2A_Matrix_hpp_
|
@ -1,342 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/A2AVectors.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: fionnoh <fionnoh@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 A2A_Vectors_hpp_
|
||||
#define A2A_Vectors_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Environment.hpp>
|
||||
#include <Hadrons/Solver.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Class to generate V & W all-to-all vectors *
|
||||
******************************************************************************/
|
||||
template <typename FImpl>
|
||||
class A2AVectorsSchurDiagTwo
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
SOLVER_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
A2AVectorsSchurDiagTwo(FMat &action, Solver &solver);
|
||||
virtual ~A2AVectorsSchurDiagTwo(void) = default;
|
||||
void makeLowModeV(FermionField &vout,
|
||||
const FermionField &evec, const Real &eval);
|
||||
void makeLowModeV5D(FermionField &vout_4d, FermionField &vout_5d,
|
||||
const FermionField &evec, const Real &eval);
|
||||
void makeLowModeW(FermionField &wout,
|
||||
const FermionField &evec, const Real &eval);
|
||||
void makeLowModeW5D(FermionField &wout_4d, FermionField &wout_5d,
|
||||
const FermionField &evec, const Real &eval);
|
||||
void makeHighModeV(FermionField &vout, const FermionField &noise);
|
||||
void makeHighModeV5D(FermionField &vout_4d, FermionField &vout_5d,
|
||||
const FermionField &noise_5d);
|
||||
void makeHighModeW(FermionField &wout, const FermionField &noise);
|
||||
void makeHighModeW5D(FermionField &vout_5d, FermionField &wout_5d,
|
||||
const FermionField &noise_5d);
|
||||
private:
|
||||
FMat &action_;
|
||||
Solver &solver_;
|
||||
GridBase *fGrid_, *frbGrid_, *gGrid_;
|
||||
bool is5d_;
|
||||
FermionField src_o_, sol_e_, sol_o_, tmp_, tmp5_;
|
||||
SchurDiagTwoOperator<FMat, FermionField> op_;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Methods for V & W all-to-all vectors I/O *
|
||||
******************************************************************************/
|
||||
class A2AVectorsIo
|
||||
{
|
||||
public:
|
||||
struct Record: Serializable
|
||||
{
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Record,
|
||||
unsigned int, index);
|
||||
Record(void): index(0) {}
|
||||
};
|
||||
public:
|
||||
template <typename Field>
|
||||
static void write(const std::string fileStem, std::vector<Field> &vec,
|
||||
const bool multiFile, const int trajectory = -1);
|
||||
template <typename Field>
|
||||
static void read(std::vector<Field> &vec, const std::string fileStem,
|
||||
const bool multiFile, const int trajectory = -1);
|
||||
private:
|
||||
static inline std::string vecFilename(const std::string stem, const int traj,
|
||||
const bool multiFile)
|
||||
{
|
||||
std::string t = (traj < 0) ? "" : ("." + std::to_string(traj));
|
||||
|
||||
if (multiFile)
|
||||
{
|
||||
return stem + t;
|
||||
}
|
||||
else
|
||||
{
|
||||
return stem + t + ".bin";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* A2AVectorsSchurDiagTwo template implementation *
|
||||
******************************************************************************/
|
||||
template <typename FImpl>
|
||||
A2AVectorsSchurDiagTwo<FImpl>::A2AVectorsSchurDiagTwo(FMat &action, Solver &solver)
|
||||
: action_(action)
|
||||
, solver_(solver)
|
||||
, fGrid_(action_.FermionGrid())
|
||||
, frbGrid_(action_.FermionRedBlackGrid())
|
||||
, gGrid_(action_.GaugeGrid())
|
||||
, src_o_(frbGrid_)
|
||||
, sol_e_(frbGrid_)
|
||||
, sol_o_(frbGrid_)
|
||||
, tmp_(frbGrid_)
|
||||
, tmp5_(fGrid_)
|
||||
, op_(action_)
|
||||
{}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeV(FermionField &vout, const FermionField &evec, const Real &eval)
|
||||
{
|
||||
src_o_ = evec;
|
||||
src_o_.checkerboard = Odd;
|
||||
pickCheckerboard(Even, sol_e_, vout);
|
||||
pickCheckerboard(Odd, sol_o_, vout);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// v_ie = -(1/eval_i) * MeeInv Meo MooInv evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
action_.MooeeInv(src_o_, tmp_);
|
||||
assert(tmp_.checkerboard == Odd);
|
||||
action_.Meooe(tmp_, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
action_.MooeeInv(sol_e_, tmp_);
|
||||
assert(tmp_.checkerboard == Even);
|
||||
sol_e_ = (-1.0 / eval) * tmp_;
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// v_io = (1/eval_i) * MooInv evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
action_.MooeeInv(src_o_, tmp_);
|
||||
assert(tmp_.checkerboard == Odd);
|
||||
sol_o_ = (1.0 / eval) * tmp_;
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
setCheckerboard(vout, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
setCheckerboard(vout, sol_o_);
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeV5D(FermionField &vout_4d, FermionField &vout_5d, const FermionField &evec, const Real &eval)
|
||||
{
|
||||
makeLowModeV(vout_5d, evec, eval);
|
||||
action_.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeW(FermionField &wout, const FermionField &evec, const Real &eval)
|
||||
{
|
||||
src_o_ = evec;
|
||||
src_o_.checkerboard = Odd;
|
||||
pickCheckerboard(Even, sol_e_, wout);
|
||||
pickCheckerboard(Odd, sol_o_, wout);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// w_ie = - MeeInvDag MoeDag Doo evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
op_.Mpc(src_o_, tmp_);
|
||||
assert(tmp_.checkerboard == Odd);
|
||||
action_.MeooeDag(tmp_, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
action_.MooeeInvDag(sol_e_, tmp_);
|
||||
assert(tmp_.checkerboard == Even);
|
||||
sol_e_ = (-1.0) * tmp_;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// w_io = Doo evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
op_.Mpc(src_o_, sol_o_);
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
setCheckerboard(wout, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
setCheckerboard(wout, sol_o_);
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeW5D(FermionField &wout_4d,
|
||||
FermionField &wout_5d,
|
||||
const FermionField &evec,
|
||||
const Real &eval)
|
||||
{
|
||||
makeLowModeW(tmp5_, evec, eval);
|
||||
action_.DminusDag(tmp5_, wout_5d);
|
||||
action_.ExportPhysicalFermionSource(wout_5d, wout_4d);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeV(FermionField &vout,
|
||||
const FermionField &noise)
|
||||
{
|
||||
solver_(vout, noise);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeV5D(FermionField &vout_4d,
|
||||
FermionField &vout_5d,
|
||||
const FermionField &noise)
|
||||
{
|
||||
if (noise._grid->Dimensions() == fGrid_->Dimensions() - 1)
|
||||
{
|
||||
action_.ImportPhysicalFermionSource(noise, tmp5_);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp5_ = noise;
|
||||
}
|
||||
makeHighModeV(vout_5d, tmp5_);
|
||||
action_.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeW(FermionField &wout,
|
||||
const FermionField &noise)
|
||||
{
|
||||
wout = noise;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeW5D(FermionField &wout_4d,
|
||||
FermionField &wout_5d,
|
||||
const FermionField &noise)
|
||||
{
|
||||
if (noise._grid->Dimensions() == fGrid_->Dimensions() - 1)
|
||||
{
|
||||
action_.ImportUnphysicalFermion(noise, wout_5d);
|
||||
wout_4d = noise;
|
||||
}
|
||||
else
|
||||
{
|
||||
wout_5d = noise;
|
||||
action_.ExportPhysicalFermionSource(wout_5d, wout_4d);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* all-to-all vectors I/O template implementation *
|
||||
******************************************************************************/
|
||||
template <typename Field>
|
||||
void A2AVectorsIo::write(const std::string fileStem, std::vector<Field> &vec,
|
||||
const bool multiFile, const int trajectory)
|
||||
{
|
||||
Record record;
|
||||
GridBase *grid = vec[0]._grid;
|
||||
ScidacWriter binWriter(grid->IsBoss());
|
||||
std::string filename = vecFilename(fileStem, trajectory, multiFile);
|
||||
|
||||
if (multiFile)
|
||||
{
|
||||
std::string fullFilename;
|
||||
|
||||
for (unsigned int i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
fullFilename = filename + "/elem" + std::to_string(i) + ".bin";
|
||||
|
||||
LOG(Message) << "Writing vector " << i << std::endl;
|
||||
makeFileDir(fullFilename, grid);
|
||||
binWriter.open(fullFilename);
|
||||
record.index = i;
|
||||
binWriter.writeScidacFieldRecord(vec[i], record);
|
||||
binWriter.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
makeFileDir(filename, grid);
|
||||
binWriter.open(filename);
|
||||
for (unsigned int i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
LOG(Message) << "Writing vector " << i << std::endl;
|
||||
record.index = i;
|
||||
binWriter.writeScidacFieldRecord(vec[i], record);
|
||||
}
|
||||
binWriter.close();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Field>
|
||||
void A2AVectorsIo::read(std::vector<Field> &vec, const std::string fileStem,
|
||||
const bool multiFile, const int trajectory)
|
||||
{
|
||||
Record record;
|
||||
ScidacReader binReader;
|
||||
std::string filename = vecFilename(fileStem, trajectory, multiFile);
|
||||
|
||||
if (multiFile)
|
||||
{
|
||||
std::string fullFilename;
|
||||
|
||||
for (unsigned int i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
fullFilename = filename + "/elem" + std::to_string(i) + ".bin";
|
||||
|
||||
LOG(Message) << "Reading vector " << i << std::endl;
|
||||
binReader.open(fullFilename);
|
||||
binReader.readScidacFieldRecord(vec[i], record);
|
||||
binReader.close();
|
||||
if (record.index != i)
|
||||
{
|
||||
HADRONS_ERROR(Io, "vector index mismatch");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
binReader.open(filename);
|
||||
for (unsigned int i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
LOG(Message) << "Reading vector " << i << std::endl;
|
||||
binReader.readScidacFieldRecord(vec[i], record);
|
||||
if (record.index != i)
|
||||
{
|
||||
HADRONS_ERROR(Io, "vector index mismatch");
|
||||
}
|
||||
}
|
||||
binReader.close();
|
||||
}
|
||||
}
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // A2A_Vectors_hpp_
|
@ -1,250 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/DilutedNoise.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
Author: Vera Guelpers <vmg1n14@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 */
|
||||
#ifndef Hadrons_DilutedNoise_hpp_
|
||||
#define Hadrons_DilutedNoise_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Abstract container for diluted noise *
|
||||
******************************************************************************/
|
||||
template <typename FImpl>
|
||||
class DilutedNoise
|
||||
{
|
||||
public:
|
||||
typedef typename FImpl::FermionField FermionField;
|
||||
public:
|
||||
// constructor/destructor
|
||||
DilutedNoise(GridCartesian *g);
|
||||
DilutedNoise(GridCartesian *g, const unsigned int nNoise);
|
||||
virtual ~DilutedNoise(void) = default;
|
||||
// access
|
||||
std::vector<FermionField> & getNoise(void);
|
||||
const std::vector<FermionField> & getNoise(void) const;
|
||||
const FermionField & operator[](const unsigned int i) const;
|
||||
FermionField & operator[](const unsigned int i);
|
||||
void resize(const unsigned int nNoise);
|
||||
unsigned int size(void) const;
|
||||
GridCartesian *getGrid(void) const;
|
||||
// generate noise (pure virtual)
|
||||
virtual void generateNoise(GridParallelRNG &rng) = 0;
|
||||
private:
|
||||
std::vector<FermionField> noise_;
|
||||
GridCartesian *grid_;
|
||||
unsigned int nNoise_;
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TimeDilutedSpinColorDiagonalNoise: public DilutedNoise<FImpl>
|
||||
{
|
||||
public:
|
||||
typedef typename FImpl::FermionField FermionField;
|
||||
public:
|
||||
// constructor/destructor
|
||||
TimeDilutedSpinColorDiagonalNoise(GridCartesian *g);
|
||||
virtual ~TimeDilutedSpinColorDiagonalNoise(void) = default;
|
||||
// generate noise
|
||||
virtual void generateNoise(GridParallelRNG &rng);
|
||||
private:
|
||||
unsigned int nt_;
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class FullVolumeSpinColorDiagonalNoise: public DilutedNoise<FImpl>
|
||||
{
|
||||
public:
|
||||
typedef typename FImpl::FermionField FermionField;
|
||||
public:
|
||||
// constructor/destructor
|
||||
FullVolumeSpinColorDiagonalNoise(GridCartesian *g, unsigned int n_src);
|
||||
virtual ~FullVolumeSpinColorDiagonalNoise(void) = default;
|
||||
// generate noise
|
||||
virtual void generateNoise(GridParallelRNG &rng);
|
||||
private:
|
||||
unsigned int nSrc_;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* DilutedNoise template implementation *
|
||||
******************************************************************************/
|
||||
template <typename FImpl>
|
||||
DilutedNoise<FImpl>::DilutedNoise(GridCartesian *g)
|
||||
: grid_(g)
|
||||
{}
|
||||
|
||||
template <typename FImpl>
|
||||
DilutedNoise<FImpl>::DilutedNoise(GridCartesian *g,
|
||||
const unsigned int nNoise)
|
||||
: DilutedNoise(g)
|
||||
{
|
||||
resize(nNoise);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<typename DilutedNoise<FImpl>::FermionField> & DilutedNoise<FImpl>::
|
||||
getNoise(void)
|
||||
{
|
||||
return noise_;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
const std::vector<typename DilutedNoise<FImpl>::FermionField> & DilutedNoise<FImpl>::
|
||||
getNoise(void) const
|
||||
{
|
||||
return noise_;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
const typename DilutedNoise<FImpl>::FermionField &
|
||||
DilutedNoise<FImpl>::operator[](const unsigned int i) const
|
||||
{
|
||||
return noise_[i];
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
typename DilutedNoise<FImpl>::FermionField &
|
||||
DilutedNoise<FImpl>::operator[](const unsigned int i)
|
||||
{
|
||||
return noise_[i];
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void DilutedNoise<FImpl>::resize(const unsigned int nNoise)
|
||||
{
|
||||
nNoise_ = nNoise;
|
||||
noise_.resize(nNoise, grid_);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
unsigned int DilutedNoise<FImpl>::size(void) const
|
||||
{
|
||||
return noise_.size();
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
GridCartesian * DilutedNoise<FImpl>::getGrid(void) const
|
||||
{
|
||||
return grid_;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* TimeDilutedSpinColorDiagonalNoise template implementation *
|
||||
******************************************************************************/
|
||||
template <typename FImpl>
|
||||
TimeDilutedSpinColorDiagonalNoise<FImpl>::
|
||||
TimeDilutedSpinColorDiagonalNoise(GridCartesian *g)
|
||||
: DilutedNoise<FImpl>(g)
|
||||
{
|
||||
nt_ = this->getGrid()->GlobalDimensions().back();
|
||||
this->resize(nt_*Ns*FImpl::Dimension);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void TimeDilutedSpinColorDiagonalNoise<FImpl>::generateNoise(GridParallelRNG &rng)
|
||||
{
|
||||
typedef decltype(peekColour((*this)[0], 0)) SpinField;
|
||||
|
||||
auto &noise = *this;
|
||||
auto g = this->getGrid();
|
||||
auto nd = g->GlobalDimensions().size();
|
||||
auto nc = FImpl::Dimension;
|
||||
Complex shift(1., 1.);
|
||||
Lattice<iScalar<vInteger>> tLat(g);
|
||||
LatticeComplex eta(g), etaCut(g);
|
||||
SpinField etas(g);
|
||||
unsigned int i = 0;
|
||||
|
||||
LatticeCoordinate(tLat, nd - 1);
|
||||
bernoulli(rng, eta);
|
||||
eta = (2.*eta - shift)*(1./::sqrt(2.));
|
||||
for (unsigned int t = 0; t < nt_; ++t)
|
||||
{
|
||||
etaCut = where((tLat == t), eta, 0.*eta);
|
||||
for (unsigned int s = 0; s < Ns; ++s)
|
||||
{
|
||||
etas = zero;
|
||||
pokeSpin(etas, etaCut, s);
|
||||
for (unsigned int c = 0; c < nc; ++c)
|
||||
{
|
||||
noise[i] = zero;
|
||||
pokeColour(noise[i], etas, c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FullVolumeSpinColorDiagonalNoise template implementation *
|
||||
******************************************************************************/
|
||||
template <typename FImpl>
|
||||
FullVolumeSpinColorDiagonalNoise<FImpl>::
|
||||
FullVolumeSpinColorDiagonalNoise(GridCartesian *g, unsigned int nSrc)
|
||||
: DilutedNoise<FImpl>(g, nSrc*Ns*FImpl::Dimension), nSrc_(nSrc)
|
||||
{}
|
||||
|
||||
template <typename FImpl>
|
||||
void FullVolumeSpinColorDiagonalNoise<FImpl>::generateNoise(GridParallelRNG &rng)
|
||||
{
|
||||
typedef decltype(peekColour((*this)[0], 0)) SpinField;
|
||||
|
||||
auto &noise = *this;
|
||||
auto g = this->getGrid();
|
||||
auto nd = g->GlobalDimensions().size();
|
||||
auto nc = FImpl::Dimension;
|
||||
Complex shift(1., 1.);
|
||||
LatticeComplex eta(g);
|
||||
SpinField etas(g);
|
||||
unsigned int i = 0;
|
||||
|
||||
bernoulli(rng, eta);
|
||||
eta = (2.*eta - shift)*(1./::sqrt(2.));
|
||||
for (unsigned int n = 0; n < nSrc_; ++n)
|
||||
{
|
||||
for (unsigned int s = 0; s < Ns; ++s)
|
||||
{
|
||||
etas = zero;
|
||||
pokeSpin(etas, eta, s);
|
||||
for (unsigned int c = 0; c < nc; ++c)
|
||||
{
|
||||
noise[i] = zero;
|
||||
pokeColour(noise[i], etas, c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_DilutedNoise_hpp_
|
@ -1,456 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/DiskVector.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_DiskVector_hpp_
|
||||
#define Hadrons_DiskVector_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/A2AMatrix.hpp>
|
||||
#include <deque>
|
||||
#include <sys/stat.h>
|
||||
#include <ftw.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef DV_DEBUG
|
||||
#define DV_DEBUG_MSG(dv, stream) LOG(Debug) << "diskvector " << (dv) << ": " << stream << std::endl
|
||||
#else
|
||||
#define DV_DEBUG_MSG(dv, stream)
|
||||
#endif
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Abstract base class *
|
||||
******************************************************************************/
|
||||
template <typename T>
|
||||
class DiskVectorBase
|
||||
{
|
||||
public:
|
||||
typedef T ObjectType;
|
||||
|
||||
// helper for read/write vector access
|
||||
class RwAccessHelper
|
||||
{
|
||||
public:
|
||||
RwAccessHelper(DiskVectorBase<T> &master, const unsigned int i)
|
||||
: master_(master), cmaster_(master), i_(i) {}
|
||||
|
||||
// operator=: somebody is trying to store a vector element
|
||||
// write to cache and tag as modified
|
||||
T &operator=(const T &obj) const
|
||||
{
|
||||
auto &cache = *master_.cachePtr_;
|
||||
auto &modified = *master_.modifiedPtr_;
|
||||
auto &index = *master_.indexPtr_;
|
||||
|
||||
DV_DEBUG_MSG(&master_, "writing to " << i_);
|
||||
master_.cacheInsert(i_, obj);
|
||||
modified[index.at(i_)] = true;
|
||||
|
||||
return cache[index.at(i_)];
|
||||
}
|
||||
|
||||
// implicit cast to const object reference and redirection
|
||||
// to the const operator[] for read-only operations
|
||||
operator const T&() const
|
||||
{
|
||||
return cmaster_[i_];
|
||||
}
|
||||
private:
|
||||
DiskVectorBase<T> &master_;
|
||||
const DiskVectorBase<T> &cmaster_;
|
||||
const unsigned int i_;
|
||||
};
|
||||
public:
|
||||
DiskVectorBase(const std::string dirname, const unsigned int size = 0,
|
||||
const unsigned int cacheSize = 1, const bool clean = true);
|
||||
DiskVectorBase(DiskVectorBase<T> &&v) = default;
|
||||
virtual ~DiskVectorBase(void);
|
||||
const T & operator[](const unsigned int i) const;
|
||||
RwAccessHelper operator[](const unsigned int i);
|
||||
double hitRatio(void) const;
|
||||
void resetStat(void);
|
||||
private:
|
||||
virtual void load(T &obj, const std::string filename) const = 0;
|
||||
virtual void save(const std::string filename, const T &obj) const = 0;
|
||||
virtual std::string filename(const unsigned int i) const;
|
||||
void evict(void) const;
|
||||
void fetch(const unsigned int i) const;
|
||||
void cacheInsert(const unsigned int i, const T &obj) const;
|
||||
void clean(void);
|
||||
private:
|
||||
std::string dirname_;
|
||||
unsigned int size_, cacheSize_;
|
||||
double access_{0.}, hit_{0.};
|
||||
bool clean_;
|
||||
// using pointers to allow modifications when class is const
|
||||
// semantic: const means data unmodified, but cache modification allowed
|
||||
std::unique_ptr<std::vector<T>> cachePtr_;
|
||||
std::unique_ptr<std::vector<bool>> modifiedPtr_;
|
||||
std::unique_ptr<std::map<unsigned int, unsigned int>> indexPtr_;
|
||||
std::unique_ptr<std::stack<unsigned int>> freePtr_;
|
||||
std::unique_ptr<std::deque<unsigned int>> loadsPtr_;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Specialisation for serialisable classes *
|
||||
******************************************************************************/
|
||||
template <typename T, typename Reader, typename Writer>
|
||||
class SerializableDiskVector: public DiskVectorBase<T>
|
||||
{
|
||||
public:
|
||||
using DiskVectorBase<T>::DiskVectorBase;
|
||||
private:
|
||||
virtual void load(T &obj, const std::string filename) const
|
||||
{
|
||||
Reader reader(filename);
|
||||
|
||||
read(reader, basename(filename), obj);
|
||||
}
|
||||
|
||||
virtual void save(const std::string filename, const T &obj) const
|
||||
{
|
||||
Writer writer(filename);
|
||||
|
||||
write(writer, basename(filename), obj);
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Specialisation for Eigen matrices *
|
||||
******************************************************************************/
|
||||
template <typename T>
|
||||
using EigenDiskVectorMat = A2AMatrix<T>;
|
||||
|
||||
template <typename T>
|
||||
class EigenDiskVector: public DiskVectorBase<EigenDiskVectorMat<T>>
|
||||
{
|
||||
public:
|
||||
using DiskVectorBase<EigenDiskVectorMat<T>>::DiskVectorBase;
|
||||
typedef EigenDiskVectorMat<T> Matrix;
|
||||
public:
|
||||
T operator()(const unsigned int i, const Eigen::Index j,
|
||||
const Eigen::Index k) const
|
||||
{
|
||||
return (*this)[i](j, k);
|
||||
}
|
||||
private:
|
||||
virtual void load(EigenDiskVectorMat<T> &obj, const std::string filename) const
|
||||
{
|
||||
std::ifstream f(filename, std::ios::binary);
|
||||
uint32_t crc, check;
|
||||
Eigen::Index nRow, nCol;
|
||||
size_t matSize;
|
||||
double tRead, tHash;
|
||||
|
||||
f.read(reinterpret_cast<char *>(&crc), sizeof(crc));
|
||||
f.read(reinterpret_cast<char *>(&nRow), sizeof(nRow));
|
||||
f.read(reinterpret_cast<char *>(&nCol), sizeof(nCol));
|
||||
obj.resize(nRow, nCol);
|
||||
matSize = nRow*nCol*sizeof(T);
|
||||
tRead = -usecond();
|
||||
f.read(reinterpret_cast<char *>(obj.data()), matSize);
|
||||
tRead += usecond();
|
||||
tHash = -usecond();
|
||||
#ifdef USE_IPP
|
||||
check = GridChecksum::crc32c(obj.data(), matSize);
|
||||
#else
|
||||
check = GridChecksum::crc32(obj.data(), matSize);
|
||||
#endif
|
||||
tHash += usecond();
|
||||
DV_DEBUG_MSG(this, "Eigen read " << tRead/1.0e6 << " sec " << matSize/tRead*1.0e6/1024/1024 << " MB/s");
|
||||
DV_DEBUG_MSG(this, "Eigen crc32 " << std::hex << check << std::dec
|
||||
<< " " << tHash/1.0e6 << " sec " << matSize/tHash*1.0e6/1024/1024 << " MB/s");
|
||||
if (crc != check)
|
||||
{
|
||||
HADRONS_ERROR(Io, "checksum failed")
|
||||
}
|
||||
}
|
||||
|
||||
virtual void save(const std::string filename, const EigenDiskVectorMat<T> &obj) const
|
||||
{
|
||||
std::ofstream f(filename, std::ios::binary);
|
||||
uint32_t crc;
|
||||
Eigen::Index nRow, nCol;
|
||||
size_t matSize;
|
||||
double tWrite, tHash;
|
||||
|
||||
nRow = obj.rows();
|
||||
nCol = obj.cols();
|
||||
matSize = nRow*nCol*sizeof(T);
|
||||
tHash = -usecond();
|
||||
#ifdef USE_IPP
|
||||
crc = GridChecksum::crc32c(obj.data(), matSize);
|
||||
#else
|
||||
crc = GridChecksum::crc32(obj.data(), matSize);
|
||||
#endif
|
||||
tHash += usecond();
|
||||
f.write(reinterpret_cast<char *>(&crc), sizeof(crc));
|
||||
f.write(reinterpret_cast<char *>(&nRow), sizeof(nRow));
|
||||
f.write(reinterpret_cast<char *>(&nCol), sizeof(nCol));
|
||||
tWrite = -usecond();
|
||||
f.write(reinterpret_cast<const char *>(obj.data()), matSize);
|
||||
tWrite += usecond();
|
||||
DV_DEBUG_MSG(this, "Eigen write " << tWrite/1.0e6 << " sec " << matSize/tWrite*1.0e6/1024/1024 << " MB/s");
|
||||
DV_DEBUG_MSG(this, "Eigen crc32 " << std::hex << crc << std::dec
|
||||
<< " " << tHash/1.0e6 << " sec " << matSize/tHash*1.0e6/1024/1024 << " MB/s");
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* DiskVectorBase implementation *
|
||||
******************************************************************************/
|
||||
template <typename T>
|
||||
DiskVectorBase<T>::DiskVectorBase(const std::string dirname,
|
||||
const unsigned int size,
|
||||
const unsigned int cacheSize,
|
||||
const bool clean)
|
||||
: dirname_(dirname), size_(size), cacheSize_(cacheSize), clean_(clean)
|
||||
, cachePtr_(new std::vector<T>(size))
|
||||
, modifiedPtr_(new std::vector<bool>(size, false))
|
||||
, indexPtr_(new std::map<unsigned int, unsigned int>())
|
||||
, freePtr_(new std::stack<unsigned int>)
|
||||
, loadsPtr_(new std::deque<unsigned int>())
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if(stat(dirname.c_str(), &s) == 0)
|
||||
{
|
||||
HADRONS_ERROR(Io, "directory '" + dirname + "' already exists")
|
||||
}
|
||||
mkdir(dirname);
|
||||
for (unsigned int i = 0; i < cacheSize_; ++i)
|
||||
{
|
||||
freePtr_->push(i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DiskVectorBase<T>::~DiskVectorBase(void)
|
||||
{
|
||||
if (clean_)
|
||||
{
|
||||
clean();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T & DiskVectorBase<T>::operator[](const unsigned int i) const
|
||||
{
|
||||
auto &cache = *cachePtr_;
|
||||
auto &index = *indexPtr_;
|
||||
auto &freeInd = *freePtr_;
|
||||
auto &loads = *loadsPtr_;
|
||||
|
||||
DV_DEBUG_MSG(this, "accessing " << i << " (RO)");
|
||||
|
||||
if (i >= size_)
|
||||
{
|
||||
HADRONS_ERROR(Size, "index out of range");
|
||||
}
|
||||
const_cast<double &>(access_)++;
|
||||
if (index.find(i) == index.end())
|
||||
{
|
||||
// cache miss
|
||||
DV_DEBUG_MSG(this, "cache miss");
|
||||
fetch(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
DV_DEBUG_MSG(this, "cache hit");
|
||||
|
||||
auto pos = std::find(loads.begin(), loads.end(), i);
|
||||
|
||||
const_cast<double &>(hit_)++;
|
||||
loads.erase(pos);
|
||||
loads.push_back(i);
|
||||
}
|
||||
|
||||
#ifdef DV_DEBUG
|
||||
std::string msg;
|
||||
|
||||
for (auto &p: loads)
|
||||
{
|
||||
msg += std::to_string(p) + " ";
|
||||
}
|
||||
DV_DEBUG_MSG(this, "in cache: " << msg);
|
||||
#endif
|
||||
|
||||
return cache[index.at(i)];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename DiskVectorBase<T>::RwAccessHelper DiskVectorBase<T>::operator[](const unsigned int i)
|
||||
{
|
||||
DV_DEBUG_MSG(this, "accessing " << i << " (RW)");
|
||||
|
||||
if (i >= size_)
|
||||
{
|
||||
HADRONS_ERROR(Size, "index out of range");
|
||||
}
|
||||
|
||||
return RwAccessHelper(*this, i);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
double DiskVectorBase<T>::hitRatio(void) const
|
||||
{
|
||||
return hit_/access_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DiskVectorBase<T>::resetStat(void)
|
||||
{
|
||||
access_ = 0.;
|
||||
hit_ = 0.;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::string DiskVectorBase<T>::filename(const unsigned int i) const
|
||||
{
|
||||
return dirname_ + "/elem_" + std::to_string(i);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DiskVectorBase<T>::evict(void) const
|
||||
{
|
||||
auto &cache = *cachePtr_;
|
||||
auto &modified = *modifiedPtr_;
|
||||
auto &index = *indexPtr_;
|
||||
auto &freeInd = *freePtr_;
|
||||
auto &loads = *loadsPtr_;
|
||||
|
||||
if (index.size() >= cacheSize_)
|
||||
{
|
||||
unsigned int i = loads.front();
|
||||
|
||||
DV_DEBUG_MSG(this, "evicting " << i);
|
||||
if (modified[index.at(i)])
|
||||
{
|
||||
DV_DEBUG_MSG(this, "element " << i << " modified, saving to disk");
|
||||
save(filename(i), cache[index.at(i)]);
|
||||
}
|
||||
freeInd.push(index.at(i));
|
||||
index.erase(i);
|
||||
loads.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DiskVectorBase<T>::fetch(const unsigned int i) const
|
||||
{
|
||||
auto &cache = *cachePtr_;
|
||||
auto &modified = *modifiedPtr_;
|
||||
auto &index = *indexPtr_;
|
||||
auto &freeInd = *freePtr_;
|
||||
auto &loads = *loadsPtr_;
|
||||
|
||||
struct stat s;
|
||||
|
||||
DV_DEBUG_MSG(this, "loading " << i << " from disk");
|
||||
|
||||
evict();
|
||||
|
||||
if(stat(filename(i).c_str(), &s) != 0)
|
||||
{
|
||||
HADRONS_ERROR(Io, "disk vector element " + std::to_string(i) + " uninitialised");
|
||||
}
|
||||
index[i] = freeInd.top();
|
||||
freeInd.pop();
|
||||
load(cache[index.at(i)], filename(i));
|
||||
loads.push_back(i);
|
||||
modified[index.at(i)] = false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DiskVectorBase<T>::cacheInsert(const unsigned int i, const T &obj) const
|
||||
{
|
||||
auto &cache = *cachePtr_;
|
||||
auto &modified = *modifiedPtr_;
|
||||
auto &index = *indexPtr_;
|
||||
auto &freeInd = *freePtr_;
|
||||
auto &loads = *loadsPtr_;
|
||||
|
||||
// cache miss, evict and store
|
||||
if (index.find(i) == index.end())
|
||||
{
|
||||
evict();
|
||||
index[i] = freeInd.top();
|
||||
freeInd.pop();
|
||||
cache[index.at(i)] = obj;
|
||||
loads.push_back(i);
|
||||
modified[index.at(i)] = false;
|
||||
}
|
||||
// cache hit, modify current value
|
||||
else
|
||||
{
|
||||
auto pos = std::find(loads.begin(), loads.end(), i);
|
||||
|
||||
cache[index.at(i)] = obj;
|
||||
modified[index.at(i)] = true;
|
||||
loads.erase(pos);
|
||||
loads.push_back(i);
|
||||
}
|
||||
|
||||
#ifdef DV_DEBUG
|
||||
std::string msg;
|
||||
|
||||
for (auto &p: loads)
|
||||
{
|
||||
msg += std::to_string(p) + " ";
|
||||
}
|
||||
DV_DEBUG_MSG(this, "in cache: " << msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DV_DEBUG
|
||||
#undef DV_DEBUG_MSG
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void DiskVectorBase<T>::clean(void)
|
||||
{
|
||||
auto unlink = [](const char *fpath, const struct stat *sb,
|
||||
int typeflag, struct FTW *ftwbuf)
|
||||
{
|
||||
int rv = remove(fpath);
|
||||
|
||||
if (rv)
|
||||
{
|
||||
HADRONS_ERROR(Io, "cannot remove '" + std::string(fpath) + "': "
|
||||
+ std::string(std::strerror(errno)));
|
||||
}
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
nftw(dirname_.c_str(), unlink, 64, FTW_DEPTH | FTW_PHYS);
|
||||
}
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_DiskVector_hpp_
|
@ -1,416 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/EigenPack.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_EigenPack_hpp_
|
||||
#define Hadrons_EigenPack_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Grid/algorithms/iterative/Deflation.h>
|
||||
#include <Grid/algorithms/iterative/LocalCoherenceLanczos.h>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
// Lanczos type
|
||||
#ifndef HADRONS_DEFAULT_LANCZOS_NBASIS
|
||||
#define HADRONS_DEFAULT_LANCZOS_NBASIS 60
|
||||
#endif
|
||||
|
||||
#define HADRONS_DUMP_EP_METADATA(record) \
|
||||
LOG(Message) << "Eigenpack metadata:" << std::endl;\
|
||||
LOG(Message) << "* operator" << std::endl;\
|
||||
LOG(Message) << (record).operatorXml << std::endl;\
|
||||
LOG(Message) << "* solver" << std::endl;\
|
||||
LOG(Message) << (record).solverXml << std::endl;
|
||||
|
||||
struct PackRecord
|
||||
{
|
||||
std::string operatorXml, solverXml;
|
||||
};
|
||||
|
||||
struct VecRecord: Serializable
|
||||
{
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(VecRecord,
|
||||
unsigned int, index,
|
||||
double, eval);
|
||||
VecRecord(void): index(0), eval(0.) {}
|
||||
};
|
||||
|
||||
namespace EigenPackIo
|
||||
{
|
||||
inline void readHeader(PackRecord &record, ScidacReader &binReader)
|
||||
{
|
||||
std::string recordXml;
|
||||
|
||||
binReader.readLimeObject(recordXml, SCIDAC_FILE_XML);
|
||||
XmlReader xmlReader(recordXml, true, "eigenPackPar");
|
||||
xmlReader.push();
|
||||
xmlReader.readCurrentSubtree(record.operatorXml);
|
||||
xmlReader.nextElement();
|
||||
xmlReader.readCurrentSubtree(record.solverXml);
|
||||
}
|
||||
|
||||
template <typename T, typename TIo = T>
|
||||
void readElement(T &evec, RealD &eval, const unsigned int index,
|
||||
ScidacReader &binReader, TIo *ioBuf = nullptr)
|
||||
{
|
||||
VecRecord vecRecord;
|
||||
|
||||
LOG(Message) << "Reading eigenvector " << index << std::endl;
|
||||
if (ioBuf == nullptr)
|
||||
{
|
||||
binReader.readScidacFieldRecord(evec, vecRecord);
|
||||
}
|
||||
else
|
||||
{
|
||||
binReader.readScidacFieldRecord(*ioBuf, vecRecord);
|
||||
precisionChange(evec, *ioBuf);
|
||||
}
|
||||
if (vecRecord.index != index)
|
||||
{
|
||||
HADRONS_ERROR(Io, "Eigenvector " + std::to_string(index) + " has a"
|
||||
+ " wrong index (expected " + std::to_string(vecRecord.index)
|
||||
+ ")");
|
||||
}
|
||||
eval = vecRecord.eval;
|
||||
}
|
||||
|
||||
template <typename T, typename TIo = T>
|
||||
static void readPack(std::vector<T> &evec, std::vector<RealD> &eval,
|
||||
PackRecord &record, const std::string filename,
|
||||
const unsigned int size, bool multiFile,
|
||||
GridBase *gridIo = nullptr)
|
||||
{
|
||||
std::unique_ptr<TIo> ioBuf{nullptr};
|
||||
ScidacReader binReader;
|
||||
|
||||
if (typeHash<T>() != typeHash<TIo>())
|
||||
{
|
||||
if (gridIo == nullptr)
|
||||
{
|
||||
HADRONS_ERROR(Definition,
|
||||
"I/O type different from vector type but null I/O grid passed");
|
||||
}
|
||||
ioBuf.reset(new TIo(gridIo));
|
||||
}
|
||||
if (multiFile)
|
||||
{
|
||||
std::string fullFilename;
|
||||
|
||||
for(int k = 0; k < size; ++k)
|
||||
{
|
||||
fullFilename = filename + "/v" + std::to_string(k) + ".bin";
|
||||
binReader.open(fullFilename);
|
||||
readHeader(record, binReader);
|
||||
readElement(evec[k], eval[k], k, binReader, ioBuf.get());
|
||||
binReader.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
binReader.open(filename);
|
||||
readHeader(record, binReader);
|
||||
for(int k = 0; k < size; ++k)
|
||||
{
|
||||
readElement(evec[k], eval[k], k, binReader, ioBuf.get());
|
||||
}
|
||||
binReader.close();
|
||||
}
|
||||
}
|
||||
|
||||
inline void writeHeader(ScidacWriter &binWriter, PackRecord &record)
|
||||
{
|
||||
XmlWriter xmlWriter("", "eigenPackPar");
|
||||
|
||||
xmlWriter.pushXmlString(record.operatorXml);
|
||||
xmlWriter.pushXmlString(record.solverXml);
|
||||
binWriter.writeLimeObject(1, 1, xmlWriter, "parameters", SCIDAC_FILE_XML);
|
||||
}
|
||||
|
||||
template <typename T, typename TIo = T>
|
||||
void writeElement(ScidacWriter &binWriter, T &evec, RealD &eval,
|
||||
const unsigned int index, TIo *ioBuf,
|
||||
T *testBuf = nullptr)
|
||||
{
|
||||
VecRecord vecRecord;
|
||||
|
||||
LOG(Message) << "Writing eigenvector " << index << std::endl;
|
||||
vecRecord.eval = eval;
|
||||
vecRecord.index = index;
|
||||
if ((ioBuf == nullptr) || (testBuf == nullptr))
|
||||
{
|
||||
binWriter.writeScidacFieldRecord(evec, vecRecord, DEFAULT_ASCII_PREC);
|
||||
}
|
||||
else
|
||||
{
|
||||
precisionChange(*ioBuf, evec);
|
||||
precisionChange(*testBuf, *ioBuf);
|
||||
*testBuf -= evec;
|
||||
LOG(Message) << "Precision diff norm^2 " << norm2(*testBuf) << std::endl;
|
||||
binWriter.writeScidacFieldRecord(*ioBuf, vecRecord, DEFAULT_ASCII_PREC);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename TIo = T>
|
||||
static void writePack(const std::string filename, std::vector<T> &evec,
|
||||
std::vector<RealD> &eval, PackRecord &record,
|
||||
const unsigned int size, bool multiFile,
|
||||
GridBase *gridIo = nullptr)
|
||||
{
|
||||
GridBase *grid = evec[0]._grid;
|
||||
std::unique_ptr<TIo> ioBuf{nullptr};
|
||||
std::unique_ptr<T> testBuf{nullptr};
|
||||
ScidacWriter binWriter(grid->IsBoss());
|
||||
|
||||
if (typeHash<T>() != typeHash<TIo>())
|
||||
{
|
||||
if (gridIo == nullptr)
|
||||
{
|
||||
HADRONS_ERROR(Definition,
|
||||
"I/O type different from vector type but null I/O grid passed");
|
||||
}
|
||||
ioBuf.reset(new TIo(gridIo));
|
||||
testBuf.reset(new T(grid));
|
||||
}
|
||||
if (multiFile)
|
||||
{
|
||||
std::string fullFilename;
|
||||
|
||||
for(int k = 0; k < size; ++k)
|
||||
{
|
||||
fullFilename = filename + "/v" + std::to_string(k) + ".bin";
|
||||
|
||||
makeFileDir(fullFilename, grid);
|
||||
binWriter.open(fullFilename);
|
||||
writeHeader(binWriter, record);
|
||||
writeElement(binWriter, evec[k], eval[k], k, ioBuf.get(), testBuf.get());
|
||||
binWriter.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
makeFileDir(filename, grid);
|
||||
binWriter.open(filename);
|
||||
writeHeader(binWriter, record);
|
||||
for(int k = 0; k < size; ++k)
|
||||
{
|
||||
writeElement(binWriter, evec[k], eval[k], k, ioBuf.get(), testBuf.get());
|
||||
}
|
||||
binWriter.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
class BaseEigenPack
|
||||
{
|
||||
public:
|
||||
typedef F Field;
|
||||
public:
|
||||
std::vector<RealD> eval;
|
||||
std::vector<F> evec;
|
||||
PackRecord record;
|
||||
public:
|
||||
BaseEigenPack(void) = default;
|
||||
BaseEigenPack(const size_t size, GridBase *grid)
|
||||
{
|
||||
resize(size, grid);
|
||||
}
|
||||
virtual ~BaseEigenPack(void) = default;
|
||||
void resize(const size_t size, GridBase *grid)
|
||||
{
|
||||
eval.resize(size);
|
||||
evec.resize(size, grid);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename FIo = F>
|
||||
class EigenPack: public BaseEigenPack<F>
|
||||
{
|
||||
public:
|
||||
typedef F Field;
|
||||
typedef FIo FieldIo;
|
||||
public:
|
||||
EigenPack(void) = default;
|
||||
virtual ~EigenPack(void) = default;
|
||||
|
||||
EigenPack(const size_t size, GridBase *grid, GridBase *gridIo = nullptr)
|
||||
: BaseEigenPack<F>(size, grid)
|
||||
{
|
||||
if (typeHash<F>() != typeHash<FIo>())
|
||||
{
|
||||
if (gridIo == nullptr)
|
||||
{
|
||||
HADRONS_ERROR(Definition,
|
||||
"I/O type different from vector type but null I/O grid passed");
|
||||
}
|
||||
}
|
||||
gridIo_ = gridIo;
|
||||
}
|
||||
|
||||
virtual void read(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
EigenPackIo::readPack<F, FIo>(this->evec, this->eval, this->record,
|
||||
evecFilename(fileStem, traj, multiFile),
|
||||
this->evec.size(), multiFile, gridIo_);
|
||||
HADRONS_DUMP_EP_METADATA(this->record);
|
||||
}
|
||||
|
||||
virtual void write(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
EigenPackIo::writePack<F, FIo>(evecFilename(fileStem, traj, multiFile),
|
||||
this->evec, this->eval, this->record,
|
||||
this->evec.size(), multiFile, gridIo_);
|
||||
}
|
||||
protected:
|
||||
std::string evecFilename(const std::string stem, const int traj, const bool multiFile)
|
||||
{
|
||||
std::string t = (traj < 0) ? "" : ("." + std::to_string(traj));
|
||||
|
||||
if (multiFile)
|
||||
{
|
||||
return stem + t;
|
||||
}
|
||||
else
|
||||
{
|
||||
return stem + t + ".bin";
|
||||
}
|
||||
}
|
||||
protected:
|
||||
GridBase *gridIo_;
|
||||
};
|
||||
|
||||
template <typename FineF, typename CoarseF,
|
||||
typename FineFIo = FineF, typename CoarseFIo = CoarseF>
|
||||
class CoarseEigenPack: public EigenPack<FineF, FineFIo>
|
||||
{
|
||||
public:
|
||||
typedef CoarseF CoarseField;
|
||||
typedef CoarseFIo CoarseFieldIo;
|
||||
public:
|
||||
std::vector<CoarseF> evecCoarse;
|
||||
std::vector<RealD> evalCoarse;
|
||||
public:
|
||||
CoarseEigenPack(void) = default;
|
||||
virtual ~CoarseEigenPack(void) = default;
|
||||
|
||||
CoarseEigenPack(const size_t sizeFine, const size_t sizeCoarse,
|
||||
GridBase *gridFine, GridBase *gridCoarse,
|
||||
GridBase *gridFineIo = nullptr,
|
||||
GridBase *gridCoarseIo = nullptr)
|
||||
{
|
||||
if (typeHash<FineF>() != typeHash<FineFIo>())
|
||||
{
|
||||
if (gridFineIo == nullptr)
|
||||
{
|
||||
HADRONS_ERROR(Definition,
|
||||
"Fine I/O type different from vector type but null fine I/O grid passed");
|
||||
}
|
||||
}
|
||||
if (typeHash<CoarseF>() != typeHash<CoarseFIo>())
|
||||
{
|
||||
if (gridCoarseIo == nullptr)
|
||||
{
|
||||
HADRONS_ERROR(Definition,
|
||||
"Coarse I/O type different from vector type but null coarse I/O grid passed");
|
||||
}
|
||||
}
|
||||
this->gridIo_ = gridFineIo;
|
||||
gridCoarseIo_ = gridCoarseIo;
|
||||
resize(sizeFine, sizeCoarse, gridFine, gridCoarse);
|
||||
}
|
||||
|
||||
void resize(const size_t sizeFine, const size_t sizeCoarse,
|
||||
GridBase *gridFine, GridBase *gridCoarse)
|
||||
{
|
||||
EigenPack<FineF, FineFIo>::resize(sizeFine, gridFine);
|
||||
evalCoarse.resize(sizeCoarse);
|
||||
evecCoarse.resize(sizeCoarse, gridCoarse);
|
||||
}
|
||||
|
||||
void readFine(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
EigenPack<FineF, FineFIo>::read(fileStem + "_fine", multiFile, traj);
|
||||
}
|
||||
|
||||
void readCoarse(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
PackRecord dummy;
|
||||
|
||||
EigenPackIo::readPack<CoarseF, CoarseFIo>(evecCoarse, evalCoarse, dummy,
|
||||
this->evecFilename(fileStem + "_coarse", traj, multiFile),
|
||||
evecCoarse.size(), multiFile, gridCoarseIo_);
|
||||
}
|
||||
|
||||
virtual void read(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
readFine(fileStem, multiFile, traj);
|
||||
readCoarse(fileStem, multiFile, traj);
|
||||
}
|
||||
|
||||
void writeFine(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
EigenPack<FineF, FineFIo>::write(fileStem + "_fine", multiFile, traj);
|
||||
}
|
||||
|
||||
void writeCoarse(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
EigenPackIo::writePack<CoarseF, CoarseFIo>(this->evecFilename(fileStem + "_coarse", traj, multiFile),
|
||||
evecCoarse, evalCoarse, this->record,
|
||||
evecCoarse.size(), multiFile, gridCoarseIo_);
|
||||
}
|
||||
|
||||
virtual void write(const std::string fileStem, const bool multiFile, const int traj = -1)
|
||||
{
|
||||
writeFine(fileStem, multiFile, traj);
|
||||
writeCoarse(fileStem, multiFile, traj);
|
||||
}
|
||||
private:
|
||||
GridBase *gridCoarseIo_;
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
using BaseFermionEigenPack = BaseEigenPack<typename FImpl::FermionField>;
|
||||
|
||||
template <typename FImpl, typename FImplIo = FImpl>
|
||||
using FermionEigenPack = EigenPack<typename FImpl::FermionField, typename FImplIo::FermionField>;
|
||||
|
||||
template <typename FImpl, int nBasis, typename FImplIo = FImpl>
|
||||
using CoarseFermionEigenPack = CoarseEigenPack<
|
||||
typename FImpl::FermionField,
|
||||
typename LocalCoherenceLanczos<typename FImpl::SiteSpinor,
|
||||
typename FImpl::SiteComplex,
|
||||
nBasis>::CoarseField,
|
||||
typename FImplIo::FermionField,
|
||||
typename LocalCoherenceLanczos<typename FImplIo::SiteSpinor,
|
||||
typename FImplIo::SiteComplex,
|
||||
nBasis>::CoarseField>;
|
||||
|
||||
#undef HADRONS_DUMP_EP_METADATA
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_EigenPack_hpp_
|
@ -1,71 +0,0 @@
|
||||
#include <Hadrons/Modules/MSource/Gauss.hpp>
|
||||
#include <Hadrons/Modules/MSource/Momentum.hpp>
|
||||
#include <Hadrons/Modules/MSource/SeqAslash.hpp>
|
||||
#include <Hadrons/Modules/MSource/Z2.hpp>
|
||||
#include <Hadrons/Modules/MSource/Point.hpp>
|
||||
#include <Hadrons/Modules/MSource/SeqGamma.hpp>
|
||||
#include <Hadrons/Modules/MSource/Convolution.hpp>
|
||||
#include <Hadrons/Modules/MSource/Wall.hpp>
|
||||
#include <Hadrons/Modules/MSource/SeqConserved.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/Div.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/TrKinetic.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/TrPhi.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/TwoPoint.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/Grad.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/Utils.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/StochFreeField.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/EMT.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/TrMag.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp>
|
||||
#include <Hadrons/Modules/MScalarSUN/TransProj.hpp>
|
||||
#include <Hadrons/Modules/MNoise/TimeDilutedSpinColorDiagonal.hpp>
|
||||
#include <Hadrons/Modules/MNoise/FullVolumeSpinColorDiagonal.hpp>
|
||||
#include <Hadrons/Modules/MScalar/FreeProp.hpp>
|
||||
#include <Hadrons/Modules/MScalar/Scalar.hpp>
|
||||
#include <Hadrons/Modules/MScalar/ChargedProp.hpp>
|
||||
#include <Hadrons/Modules/MAction/Wilson.hpp>
|
||||
#include <Hadrons/Modules/MAction/ScaledDWF.hpp>
|
||||
#include <Hadrons/Modules/MAction/MobiusDWF.hpp>
|
||||
#include <Hadrons/Modules/MAction/WilsonClover.hpp>
|
||||
#include <Hadrons/Modules/MAction/ZMobiusDWF.hpp>
|
||||
#include <Hadrons/Modules/MAction/DWF.hpp>
|
||||
#include <Hadrons/Modules/MGauge/UnitEm.hpp>
|
||||
#include <Hadrons/Modules/MGauge/Electrify.hpp>
|
||||
#include <Hadrons/Modules/MGauge/StoutSmearing.hpp>
|
||||
#include <Hadrons/Modules/MGauge/Random.hpp>
|
||||
#include <Hadrons/Modules/MGauge/FundtoHirep.hpp>
|
||||
#include <Hadrons/Modules/MGauge/GaugeFix.hpp>
|
||||
#include <Hadrons/Modules/MGauge/Unit.hpp>
|
||||
#include <Hadrons/Modules/MGauge/StochEm.hpp>
|
||||
#include <Hadrons/Modules/MUtilities/RandomVectors.hpp>
|
||||
#include <Hadrons/Modules/MUtilities/PrecisionCast.hpp>
|
||||
#include <Hadrons/Modules/MIO/LoadCosmHol.hpp>
|
||||
#include <Hadrons/Modules/MIO/LoadA2AVectors.hpp>
|
||||
#include <Hadrons/Modules/MIO/LoadEigenPack.hpp>
|
||||
#include <Hadrons/Modules/MIO/LoadNersc.hpp>
|
||||
#include <Hadrons/Modules/MIO/LoadBinary.hpp>
|
||||
#include <Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp>
|
||||
#include <Hadrons/Modules/MContraction/WeakEye3pt.hpp>
|
||||
#include <Hadrons/Modules/MContraction/WeakMesonDecayKl2.hpp>
|
||||
#include <Hadrons/Modules/MContraction/Gamma3pt.hpp>
|
||||
#include <Hadrons/Modules/MContraction/A2AMesonField.hpp>
|
||||
#include <Hadrons/Modules/MContraction/A2ALoop.hpp>
|
||||
#include <Hadrons/Modules/MContraction/WeakNonEye3pt.hpp>
|
||||
#include <Hadrons/Modules/MContraction/DiscLoop.hpp>
|
||||
#include <Hadrons/Modules/MContraction/A2AAslashField.hpp>
|
||||
#include <Hadrons/Modules/MContraction/Baryon.hpp>
|
||||
#include <Hadrons/Modules/MContraction/Meson.hpp>
|
||||
#include <Hadrons/Modules/MNPR/FourQuark.hpp>
|
||||
#include <Hadrons/Modules/MNPR/Bilinear.hpp>
|
||||
#include <Hadrons/Modules/MNPR/Amputate.hpp>
|
||||
#include <Hadrons/Modules/MSolver/A2AAslashVectors.hpp>
|
||||
#include <Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
||||
#include <Hadrons/Modules/MSolver/Guesser.hpp>
|
||||
#include <Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp>
|
||||
#include <Hadrons/Modules/MSolver/A2AVectors.hpp>
|
||||
#include <Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp>
|
||||
#include <Hadrons/Modules/MFermion/FreeProp.hpp>
|
||||
#include <Hadrons/Modules/MFermion/GaugeProp.hpp>
|
||||
#include <Hadrons/Modules/MFermion/EMLepton.hpp>
|
||||
#include <Hadrons/Modules/MSink/Smear.hpp>
|
||||
#include <Hadrons/Modules/MSink/Point.hpp>
|
@ -1,37 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MAction/MobiusDWF.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MAction/MobiusDWF.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MAction;
|
||||
|
||||
template class Grid::Hadrons::MAction::TMobiusDWF<FIMPL>;
|
||||
#ifdef GRID_DEFAULT_PRECISION_DOUBLE
|
||||
template class Grid::Hadrons::MAction::TMobiusDWF<FIMPLF>;
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MAction/ScaledDWF.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MAction/ScaledDWF.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MAction;
|
||||
|
||||
template class Grid::Hadrons::MAction::TScaledDWF<FIMPL>;
|
||||
#ifdef GRID_DEFAULT_PRECISION_DOUBLE
|
||||
template class Grid::Hadrons::MAction::TScaledDWF<FIMPLF>;
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/A2AAslashField.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MContraction/A2AAslashField.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MContraction;
|
||||
|
||||
template class Grid::Hadrons::MContraction::TA2AAslashField<FIMPL, PhotonR>;
|
@ -1,246 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/A2AAslashField.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_MContraction_A2AAslashField_hpp_
|
||||
#define Hadrons_MContraction_A2AAslashField_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/A2AMatrix.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* A2AAslashField *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||
|
||||
class A2AAslashFieldPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AAslashFieldPar,
|
||||
int, cacheBlock,
|
||||
int, block,
|
||||
std::string, left,
|
||||
std::string, right,
|
||||
std::string, output,
|
||||
std::vector<std::string>, emField);
|
||||
};
|
||||
|
||||
class A2AAslashFieldMetadata: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AAslashFieldMetadata,
|
||||
std::string, emFieldName);
|
||||
};
|
||||
|
||||
template <typename T, typename FImpl>
|
||||
class AslashFieldKernel: public A2AKernel<T, typename FImpl::FermionField>
|
||||
{
|
||||
public:
|
||||
typedef typename FImpl::FermionField FermionField;
|
||||
public:
|
||||
AslashFieldKernel(const std::vector<LatticeComplex> &emB0,
|
||||
const std::vector<LatticeComplex> &emB1,
|
||||
GridBase *grid)
|
||||
: emB0_(emB0), emB1_(emB1), grid_(grid)
|
||||
{
|
||||
vol_ = 1.;
|
||||
for (auto &d: grid_->GlobalDimensions())
|
||||
{
|
||||
vol_ *= d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~AslashFieldKernel(void) = default;
|
||||
virtual void operator()(A2AMatrixSet<T> &m, const FermionField *left,
|
||||
const FermionField *right,
|
||||
const unsigned int orthogDim, double &t)
|
||||
{
|
||||
A2Autils<FImpl>::AslashField(m, left, right, emB0_, emB1_, orthogDim, &t);
|
||||
}
|
||||
|
||||
virtual double flops(const unsigned int blockSizei, const unsigned int blockSizej)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
|
||||
virtual double bytes(const unsigned int blockSizei, const unsigned int blockSizej)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
private:
|
||||
const std::vector<LatticeComplex> &emB0_, &emB1_;
|
||||
GridBase *grid_;
|
||||
double vol_;
|
||||
};
|
||||
|
||||
template <typename FImpl, typename PhotonImpl>
|
||||
class TA2AAslashField: public Module<A2AAslashFieldPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
typedef typename PhotonImpl::GaugeField EmField;
|
||||
typedef A2AMatrixBlockComputation<Complex,
|
||||
FermionField,
|
||||
A2AAslashFieldMetadata,
|
||||
HADRONS_A2AM_IO_TYPE> Computation;
|
||||
typedef AslashFieldKernel<Complex, FImpl> Kernel;
|
||||
public:
|
||||
// constructor
|
||||
TA2AAslashField(const std::string name);
|
||||
// destructor
|
||||
virtual ~TA2AAslashField(void) {};
|
||||
// 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_TMP(A2AAslashField, ARG(TA2AAslashField<FIMPL, PhotonR>), MContraction);
|
||||
|
||||
/******************************************************************************
|
||||
* TA2AAslashField implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename PhotonImpl>
|
||||
TA2AAslashField<FImpl, PhotonImpl>::TA2AAslashField(const std::string name)
|
||||
: Module<A2AAslashFieldPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename PhotonImpl>
|
||||
std::vector<std::string> TA2AAslashField<FImpl, PhotonImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = par().emField;
|
||||
|
||||
in.push_back(par().left);
|
||||
in.push_back(par().right);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl, typename PhotonImpl>
|
||||
std::vector<std::string> TA2AAslashField<FImpl, PhotonImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename PhotonImpl>
|
||||
void TA2AAslashField<FImpl, PhotonImpl>::setup(void)
|
||||
{
|
||||
envTmp(Computation, "computation", 1, envGetGrid(FermionField),
|
||||
env().getNd() - 1, par().emField.size(), 1, par().block,
|
||||
par().cacheBlock, this);
|
||||
envTmp(std::vector<ComplexField>, "B0", 1,
|
||||
par().emField.size(), envGetGrid(ComplexField));
|
||||
envTmp(std::vector<ComplexField>, "B1", 1,
|
||||
par().emField.size(), envGetGrid(ComplexField));
|
||||
envTmpLat(ComplexField, "Amu");
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename PhotonImpl>
|
||||
void TA2AAslashField<FImpl, PhotonImpl>::execute(void)
|
||||
{
|
||||
auto &left = envGet(std::vector<FermionField>, par().left);
|
||||
auto &right = envGet(std::vector<FermionField>, par().right);
|
||||
|
||||
int nt = env().getDim().back();
|
||||
int N_i = left.size();
|
||||
int N_j = right.size();
|
||||
int nem = par().emField.size();
|
||||
int block = par().block;
|
||||
int cacheBlock = par().cacheBlock;
|
||||
|
||||
LOG(Message) << "Computing all-to-all A-slash fields" << std::endl;
|
||||
LOG(Message) << "Left: '" << par().left << "' Right: '" << par().right << "'" << std::endl;
|
||||
LOG(Message) << "EM fields:" << std::endl;
|
||||
for (auto &name: par().emField)
|
||||
{
|
||||
LOG(Message) << " " << name << std::endl;
|
||||
}
|
||||
LOG(Message) << "A-slash field size: " << nt << "*" << N_i << "*" << N_j
|
||||
<< " (filesize " << sizeString(nt*N_i*N_j*sizeof(HADRONS_A2AM_IO_TYPE))
|
||||
<< "/EM field)" << std::endl;
|
||||
|
||||
// preparing "B" complexified fields
|
||||
startTimer("Complexify EM fields");
|
||||
envGetTmp(std::vector<ComplexField>, B0);
|
||||
envGetTmp(std::vector<ComplexField>, B1);
|
||||
for (unsigned int i = 0; i < par().emField.size(); ++i)
|
||||
{
|
||||
auto &A = envGet(EmField, par().emField[i]);
|
||||
envGetTmp(ComplexField, Amu);
|
||||
|
||||
B0[i] = peekLorentz(A, 0);
|
||||
B0[i] += timesI(peekLorentz(A, 1));
|
||||
B1[i] = peekLorentz(A, 2);
|
||||
B1[i] += timesI(peekLorentz(A, 3));
|
||||
}
|
||||
stopTimer("Complexify EM fields");
|
||||
|
||||
// I/O name & metadata lambdas
|
||||
auto ionameFn = [this](const unsigned int em, const unsigned int dummy)
|
||||
{
|
||||
return par().emField[em];
|
||||
};
|
||||
|
||||
auto filenameFn = [this, &ionameFn](const unsigned int em, const unsigned int dummy)
|
||||
{
|
||||
return par().output + "." + std::to_string(vm().getTrajectory())
|
||||
+ "/" + ionameFn(em, dummy) + ".h5";
|
||||
};
|
||||
|
||||
auto metadataFn = [this](const unsigned int em, const unsigned int dummy)
|
||||
{
|
||||
A2AAslashFieldMetadata md;
|
||||
|
||||
md.emFieldName = par().emField[em];
|
||||
|
||||
return md;
|
||||
};
|
||||
|
||||
// executing computation
|
||||
Kernel kernel(B0, B1, envGetGrid(FermionField));
|
||||
|
||||
envGetTmp(Computation, computation);
|
||||
computation.execute(left, right, kernel, ionameFn, filenameFn, metadataFn);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MContraction_A2AAslashField_hpp_
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/A2ALoop.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MContraction/A2ALoop.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MContraction;
|
||||
|
||||
template class Grid::Hadrons::MContraction::TA2ALoop<FIMPL>;
|
@ -1,35 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/A2AMesonField.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 */
|
||||
#include <Hadrons/Modules/MContraction/A2AMesonField.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MContraction;
|
||||
|
||||
template class Grid::Hadrons::MContraction::TA2AMesonField<FIMPL>;
|
@ -1,315 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/A2AMesonField.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
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 Hadrons_MContraction_A2AMesonField_hpp_
|
||||
#define Hadrons_MContraction_A2AMesonField_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/A2AMatrix.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* All-to-all meson field creation *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||
|
||||
class A2AMesonFieldPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AMesonFieldPar,
|
||||
int, cacheBlock,
|
||||
int, block,
|
||||
std::string, left,
|
||||
std::string, right,
|
||||
std::string, output,
|
||||
std::string, gammas,
|
||||
std::vector<std::string>, mom);
|
||||
};
|
||||
|
||||
class A2AMesonFieldMetadata: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AMesonFieldMetadata,
|
||||
std::vector<RealF>, momentum,
|
||||
Gamma::Algebra, gamma);
|
||||
};
|
||||
|
||||
template <typename T, typename FImpl>
|
||||
class MesonFieldKernel: public A2AKernel<T, typename FImpl::FermionField>
|
||||
{
|
||||
public:
|
||||
typedef typename FImpl::FermionField FermionField;
|
||||
public:
|
||||
MesonFieldKernel(const std::vector<Gamma::Algebra> &gamma,
|
||||
const std::vector<LatticeComplex> &mom,
|
||||
GridBase *grid)
|
||||
: gamma_(gamma), mom_(mom), grid_(grid)
|
||||
{
|
||||
vol_ = 1.;
|
||||
for (auto &d: grid_->GlobalDimensions())
|
||||
{
|
||||
vol_ *= d;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~MesonFieldKernel(void) = default;
|
||||
virtual void operator()(A2AMatrixSet<T> &m, const FermionField *left,
|
||||
const FermionField *right,
|
||||
const unsigned int orthogDim, double &t)
|
||||
{
|
||||
A2Autils<FImpl>::MesonField(m, left, right, gamma_, mom_, orthogDim, &t);
|
||||
}
|
||||
|
||||
virtual double flops(const unsigned int blockSizei, const unsigned int blockSizej)
|
||||
{
|
||||
return vol_*(2*8.0+6.0+8.0*mom_.size())*blockSizei*blockSizej*gamma_.size();
|
||||
}
|
||||
|
||||
virtual double bytes(const unsigned int blockSizei, const unsigned int blockSizej)
|
||||
{
|
||||
return vol_*(12.0*sizeof(T))*blockSizei*blockSizej
|
||||
+ vol_*(2.0*sizeof(T)*mom_.size())*blockSizei*blockSizej*gamma_.size();
|
||||
}
|
||||
private:
|
||||
const std::vector<Gamma::Algebra> &gamma_;
|
||||
const std::vector<LatticeComplex> &mom_;
|
||||
GridBase *grid_;
|
||||
double vol_;
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TA2AMesonField : public Module<A2AMesonFieldPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
typedef A2AMatrixBlockComputation<Complex,
|
||||
FermionField,
|
||||
A2AMesonFieldMetadata,
|
||||
HADRONS_A2AM_IO_TYPE> Computation;
|
||||
typedef MesonFieldKernel<Complex, FImpl> Kernel;
|
||||
public:
|
||||
// constructor
|
||||
TA2AMesonField(const std::string name);
|
||||
// destructor
|
||||
virtual ~TA2AMesonField(void){};
|
||||
// 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:
|
||||
bool hasPhase_{false};
|
||||
std::string momphName_;
|
||||
std::vector<Gamma::Algebra> gamma_;
|
||||
std::vector<std::vector<Real>> mom_;
|
||||
};
|
||||
|
||||
MODULE_REGISTER(A2AMesonField, ARG(TA2AMesonField<FIMPL>), MContraction);
|
||||
|
||||
/******************************************************************************
|
||||
* TA2AMesonField implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TA2AMesonField<FImpl>::TA2AMesonField(const std::string name)
|
||||
: Module<A2AMesonFieldPar>(name)
|
||||
, momphName_(name + "_momph")
|
||||
{
|
||||
}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TA2AMesonField<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().left, par().right};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TA2AMesonField<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TA2AMesonField<FImpl>::setup(void)
|
||||
{
|
||||
gamma_.clear();
|
||||
mom_.clear();
|
||||
if (par().gammas == "all")
|
||||
{
|
||||
gamma_ = {
|
||||
Gamma::Algebra::Gamma5,
|
||||
Gamma::Algebra::Identity,
|
||||
Gamma::Algebra::GammaX,
|
||||
Gamma::Algebra::GammaY,
|
||||
Gamma::Algebra::GammaZ,
|
||||
Gamma::Algebra::GammaT,
|
||||
Gamma::Algebra::GammaXGamma5,
|
||||
Gamma::Algebra::GammaYGamma5,
|
||||
Gamma::Algebra::GammaZGamma5,
|
||||
Gamma::Algebra::GammaTGamma5,
|
||||
Gamma::Algebra::SigmaXY,
|
||||
Gamma::Algebra::SigmaXZ,
|
||||
Gamma::Algebra::SigmaXT,
|
||||
Gamma::Algebra::SigmaYZ,
|
||||
Gamma::Algebra::SigmaYT,
|
||||
Gamma::Algebra::SigmaZT
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
gamma_ = strToVec<Gamma::Algebra>(par().gammas);
|
||||
}
|
||||
for (auto &pstr: par().mom)
|
||||
{
|
||||
auto p = strToVec<Real>(pstr);
|
||||
|
||||
if (p.size() != env().getNd() - 1)
|
||||
{
|
||||
HADRONS_ERROR(Size, "Momentum has " + std::to_string(p.size())
|
||||
+ " components instead of "
|
||||
+ std::to_string(env().getNd() - 1));
|
||||
}
|
||||
mom_.push_back(p);
|
||||
}
|
||||
envCache(std::vector<ComplexField>, momphName_, 1,
|
||||
par().mom.size(), envGetGrid(ComplexField));
|
||||
envTmpLat(ComplexField, "coor");
|
||||
envTmp(Computation, "computation", 1, envGetGrid(FermionField),
|
||||
env().getNd() - 1, mom_.size(), gamma_.size(), par().block,
|
||||
par().cacheBlock, this);
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TA2AMesonField<FImpl>::execute(void)
|
||||
{
|
||||
auto &left = envGet(std::vector<FermionField>, par().left);
|
||||
auto &right = envGet(std::vector<FermionField>, par().right);
|
||||
|
||||
int nt = env().getDim().back();
|
||||
int N_i = left.size();
|
||||
int N_j = right.size();
|
||||
int ngamma = gamma_.size();
|
||||
int nmom = mom_.size();
|
||||
int block = par().block;
|
||||
int cacheBlock = par().cacheBlock;
|
||||
|
||||
LOG(Message) << "Computing all-to-all meson fields" << std::endl;
|
||||
LOG(Message) << "Left: '" << par().left << "' Right: '" << par().right << "'" << std::endl;
|
||||
LOG(Message) << "Momenta:" << std::endl;
|
||||
for (auto &p: mom_)
|
||||
{
|
||||
LOG(Message) << " " << p << std::endl;
|
||||
}
|
||||
LOG(Message) << "Spin bilinears:" << std::endl;
|
||||
for (auto &g: gamma_)
|
||||
{
|
||||
LOG(Message) << " " << g << std::endl;
|
||||
}
|
||||
LOG(Message) << "Meson field size: " << nt << "*" << N_i << "*" << N_j
|
||||
<< " (filesize " << sizeString(nt*N_i*N_j*sizeof(HADRONS_A2AM_IO_TYPE))
|
||||
<< "/momentum/bilinear)" << std::endl;
|
||||
|
||||
auto &ph = envGet(std::vector<ComplexField>, momphName_);
|
||||
|
||||
if (!hasPhase_)
|
||||
{
|
||||
startTimer("Momentum phases");
|
||||
for (unsigned int j = 0; j < nmom; ++j)
|
||||
{
|
||||
Complex i(0.0,1.0);
|
||||
std::vector<Real> p;
|
||||
|
||||
envGetTmp(ComplexField, coor);
|
||||
ph[j] = zero;
|
||||
for(unsigned int mu = 0; mu < mom_[j].size(); mu++)
|
||||
{
|
||||
LatticeCoordinate(coor, mu);
|
||||
ph[j] = ph[j] + (mom_[j][mu]/env().getDim(mu))*coor;
|
||||
}
|
||||
ph[j] = exp((Real)(2*M_PI)*i*ph[j]);
|
||||
}
|
||||
hasPhase_ = true;
|
||||
stopTimer("Momentum phases");
|
||||
}
|
||||
|
||||
auto ionameFn = [this](const unsigned int m, const unsigned int g)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << gamma_[g] << "_";
|
||||
for (unsigned int mu = 0; mu < mom_[m].size(); ++mu)
|
||||
{
|
||||
ss << mom_[m][mu] << ((mu == mom_[m].size() - 1) ? "" : "_");
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
auto filenameFn = [this, &ionameFn](const unsigned int m, const unsigned int g)
|
||||
{
|
||||
return par().output + "." + std::to_string(vm().getTrajectory())
|
||||
+ "/" + ionameFn(m, g) + ".h5";
|
||||
};
|
||||
|
||||
auto metadataFn = [this](const unsigned int m, const unsigned int g)
|
||||
{
|
||||
A2AMesonFieldMetadata md;
|
||||
|
||||
for (auto pmu: mom_[m])
|
||||
{
|
||||
md.momentum.push_back(pmu);
|
||||
}
|
||||
md.gamma = gamma_[g];
|
||||
|
||||
return md;
|
||||
};
|
||||
|
||||
Kernel kernel(gamma_, ph, envGetGrid(FermionField));
|
||||
|
||||
envGetTmp(Computation, computation);
|
||||
computation.execute(left, right, kernel, ionameFn, filenameFn, metadataFn);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MContraction_A2AMesonField_hpp_
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/WeakEye3pt.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MContraction/WeakEye3pt.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MContraction;
|
||||
|
||||
template class Grid::Hadrons::MContraction::TWeakEye3pt<FIMPL>;
|
@ -1,200 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/WeakEye3pt.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_WeakEye3pt_hpp_
|
||||
#define Hadrons_MContraction_WeakEye3pt_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/*
|
||||
* Weak Hamiltonian meson 3-pt diagrams, eye topologies.
|
||||
*
|
||||
* Schematics: loop |
|
||||
* /-<-¬ |
|
||||
* / \ | qbl G qbr
|
||||
* \ / | /----<------*------<----¬
|
||||
* qbl \ / qbr | / /-*-¬ \
|
||||
* /-----<-----* *-----<----¬ | / / G \ \
|
||||
* gIn * G G * gOut | gIn * \ / loop * gOut
|
||||
* \ / | \ \->-/ /
|
||||
* \ / | \ /
|
||||
* \---------->---------/ | \----------->----------/
|
||||
* qs | qs
|
||||
* |
|
||||
* one trace | two traces
|
||||
*
|
||||
* one trace : tr(qbr*gOut*qs*adj(gIn)*g5*adj(qbl)*g5*G*loop*G)
|
||||
* two traces: tr(qbr*gOut*qs*adj(gIn)*g5*adj(qbl)*g5*G)*tr(loop*G)
|
||||
*
|
||||
*/
|
||||
|
||||
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||
|
||||
class WeakEye3ptPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(WeakEye3ptPar,
|
||||
std::string, qBarLeft,
|
||||
std::string, qBarRight,
|
||||
std::string, qSpectator,
|
||||
std::string, loop,
|
||||
unsigned int, tOut,
|
||||
Gamma::Algebra, gammaIn,
|
||||
Gamma::Algebra, gammaOut,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TWeakEye3pt: public Module<WeakEye3ptPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
class Metadata: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Metadata,
|
||||
Gamma::Algebra, in,
|
||||
Gamma::Algebra, out,
|
||||
Gamma::Algebra, op,
|
||||
unsigned int, trace);
|
||||
};
|
||||
typedef Correlator<Metadata> Result;
|
||||
public:
|
||||
// constructor
|
||||
TWeakEye3pt(const std::string name);
|
||||
// destructor
|
||||
virtual ~TWeakEye3pt(void) {};
|
||||
// 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_TMP(WeakEye3pt, TWeakEye3pt<FIMPL>, MContraction);
|
||||
|
||||
/******************************************************************************
|
||||
* TWeakEye3pt implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TWeakEye3pt<FImpl>::TWeakEye3pt(const std::string name)
|
||||
: Module<WeakEye3ptPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TWeakEye3pt<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().qBarLeft, par().qBarRight,
|
||||
par().qSpectator, par().loop};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TWeakEye3pt<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TWeakEye3pt<FImpl>::setup(void)
|
||||
{
|
||||
envTmpLat(ComplexField, "corr");
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TWeakEye3pt<FImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Computing mesonic weak 3pt contractions, eye topologies" << std::endl;
|
||||
LOG(Message) << "gIn : " << par().gammaIn << std::endl;
|
||||
LOG(Message) << "gOut: " << par().gammaIn << std::endl;
|
||||
LOG(Message) << "tOut: " << par().tOut << std::endl;
|
||||
LOG(Message) << "qbl : " << par().qBarLeft << std::endl;
|
||||
LOG(Message) << "qbr : " << par().qBarRight << std::endl;
|
||||
LOG(Message) << "qs : " << par().qSpectator << std::endl;
|
||||
LOG(Message) << "loop: " << par().loop << std::endl;
|
||||
|
||||
std::vector<Result> result;
|
||||
Result r;
|
||||
auto &qbl = envGet(PropagatorField, par().qBarLeft);
|
||||
auto &qbr = envGet(PropagatorField, par().qBarRight);
|
||||
auto &loop = envGet(PropagatorField, par().loop);
|
||||
auto &qs = envGet(SlicedPropagator, par().qSpectator);
|
||||
auto qst = qs[par().tOut];
|
||||
Gamma gIn(par().gammaIn), gOut(par().gammaOut);
|
||||
Gamma g5(Gamma::Algebra::Gamma5);
|
||||
|
||||
envGetTmp(ComplexField, corr);
|
||||
r.info.in = par().gammaIn;
|
||||
r.info.out = par().gammaOut;
|
||||
for (auto &G: Gamma::gall)
|
||||
{
|
||||
SlicedComplex buf;
|
||||
|
||||
r.info.op = G.g;
|
||||
// one trace
|
||||
corr = trace(qbr*gOut*qst*adj(gIn)*g5*adj(qbl)*g5*G*loop*G);
|
||||
sliceSum(corr, buf, Tp);
|
||||
r.corr.clear();
|
||||
for (unsigned int t = 0; t < buf.size(); ++t)
|
||||
{
|
||||
r.corr.push_back(TensorRemove(buf[t]));
|
||||
}
|
||||
r.info.trace = 1;
|
||||
result.push_back(r);
|
||||
// two traces
|
||||
corr = trace(qbr*gOut*qst*adj(gIn)*g5*adj(qbl)*g5*G)*trace(loop*G);
|
||||
sliceSum(corr, buf, Tp);
|
||||
r.corr.clear();
|
||||
for (unsigned int t = 0; t < buf.size(); ++t)
|
||||
{
|
||||
r.corr.push_back(TensorRemove(buf[t]));
|
||||
}
|
||||
r.info.trace = 2;
|
||||
result.push_back(r);
|
||||
}
|
||||
saveResult(par().output, "weakEye3pt", result);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MContraction_WeakEye3pt_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/WeakMesonDecayKl2.cc
|
||||
|
||||
Copyright (C) 2015-2018
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Hadrons/Modules/MContraction/WeakMesonDecayKl2.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MContraction;
|
||||
|
||||
template class Grid::Hadrons::MContraction::TWeakMesonDecayKl2<FIMPL>;
|
||||
|
@ -1,185 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/WeakMesonDecayKl2.hpp
|
||||
|
||||
Copyright (C) 2015-2018
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@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_MContraction_WeakMesonDecayKl2_hpp_
|
||||
#define Hadrons_MContraction_WeakMesonDecayKl2_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/*
|
||||
* Kl2 contraction
|
||||
* -----------------------------
|
||||
*
|
||||
* contraction for Kl2 decay, including the lepton
|
||||
*
|
||||
* trace(q1*adj(q2)*g5*gL[mu]) * (gL[mu] * lepton)_{a,b}
|
||||
*
|
||||
* with open spinor indices (a,b) for the lepton part
|
||||
*
|
||||
* q1 lepton
|
||||
* /------------\ /------------
|
||||
* / \ /
|
||||
* / \H_W/
|
||||
* g_5 * * *
|
||||
* \ /
|
||||
* \ /
|
||||
* \____________/
|
||||
* q2
|
||||
*
|
||||
* * options:
|
||||
* - q1: input propagator 1 (string)
|
||||
* - q2: input propagator 2 (string)
|
||||
* - lepton: input lepton (string)
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* TWeakMesonDecayKl2 *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||
|
||||
class WeakMesonDecayKl2Par: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(WeakMesonDecayKl2Par,
|
||||
std::string, q1,
|
||||
std::string, q2,
|
||||
std::string, lepton,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TWeakMesonDecayKl2: public Module<WeakMesonDecayKl2Par>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
typedef typename SpinMatrixField::vector_object::scalar_object SpinMatrix;
|
||||
class Result: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||
std::vector<SpinMatrix>, corr);
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
TWeakMesonDecayKl2(const std::string name);
|
||||
// destructor
|
||||
virtual ~TWeakMesonDecayKl2(void) {};
|
||||
// dependencies/products
|
||||
virtual std::vector<std::string> getInput(void);
|
||||
virtual std::vector<std::string> getOutput(void);
|
||||
protected:
|
||||
// execution
|
||||
virtual void setup(void);
|
||||
// execution
|
||||
virtual void execute(void);
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(WeakMesonDecayKl2, TWeakMesonDecayKl2<FIMPL>, MContraction);
|
||||
|
||||
/******************************************************************************
|
||||
* TWeakMesonDecayKl2 implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TWeakMesonDecayKl2<FImpl>::TWeakMesonDecayKl2(const std::string name)
|
||||
: Module<WeakMesonDecayKl2Par>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TWeakMesonDecayKl2<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> input = {par().q1, par().q2, par().lepton};
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TWeakMesonDecayKl2<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> output = {};
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// setup ////////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TWeakMesonDecayKl2<FImpl>::setup(void)
|
||||
{
|
||||
envTmpLat(ComplexField, "c");
|
||||
envTmpLat(PropagatorField, "prop_buf");
|
||||
envCreateLat(PropagatorField, getName());
|
||||
envTmpLat(SpinMatrixField, "buf");
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TWeakMesonDecayKl2<FImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Computing QED Kl2 contractions '" << getName() << "' using"
|
||||
<< " quarks '" << par().q1 << "' and '" << par().q2 << "' and"
|
||||
<< "lepton '" << par().lepton << "'" << std::endl;
|
||||
|
||||
Gamma g5(Gamma::Algebra::Gamma5);
|
||||
int nt = env().getDim(Tp);
|
||||
std::vector<SpinMatrix> res_summed;
|
||||
Result r;
|
||||
|
||||
auto &res = envGet(PropagatorField, getName()); res = zero;
|
||||
auto &q1 = envGet(PropagatorField, par().q1);
|
||||
auto &q2 = envGet(PropagatorField, par().q2);
|
||||
auto &lepton = envGet(PropagatorField, par().lepton);
|
||||
envGetTmp(SpinMatrixField, buf);
|
||||
envGetTmp(ComplexField, c);
|
||||
envGetTmp(PropagatorField, prop_buf);
|
||||
|
||||
for (unsigned int mu = 0; mu < 4; ++mu)
|
||||
{
|
||||
c = zero;
|
||||
//hadronic part: trace(q1*adj(q2)*g5*gL[mu])
|
||||
c = trace(q1*adj(q2)*g5*GammaL(Gamma::gmu[mu]));
|
||||
prop_buf = 1.;
|
||||
//multiply lepton part
|
||||
res += c * prop_buf * GammaL(Gamma::gmu[mu]) * lepton;
|
||||
}
|
||||
buf = peekColour(res, 0, 0);
|
||||
sliceSum(buf, r.corr, Tp);
|
||||
saveResult(par().output, "weakdecay", r);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MContraction_WeakMesonDecayKl2_hpp_
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/WeakNonEye3pt.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MContraction/WeakNonEye3pt.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MContraction;
|
||||
|
||||
template class Grid::Hadrons::MContraction::TWeakNonEye3pt<FIMPL>;
|
@ -1,198 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MContraction/WeakNonEye3pt.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_WeakNonEye3pt_hpp_
|
||||
#define Hadrons_MContraction_WeakNonEye3pt_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/*
|
||||
* Weak Hamiltonian meson 3-pt diagrams, non-eye topologies.
|
||||
*
|
||||
* Schematic:
|
||||
* qbl qbr | qbl qbr
|
||||
* /--<--¬ /--<--¬ | /--<--¬ /--<--¬
|
||||
* / \ / \ | / \ / \
|
||||
* / \ / \ | / \ / \
|
||||
* / \ / \ | / \ / \
|
||||
* gIn * * G * gOut | gIn * G * * G * gOut
|
||||
* \ * G | | \ / \ /
|
||||
* \ / \ / | \ / \ /
|
||||
* \ / \ / | \ / \ /
|
||||
* \ / \ / | \-->--/ \-->--/
|
||||
* \-->--/ \-->--/ | ql qr
|
||||
* ql qr |
|
||||
* one trace | two traces
|
||||
*
|
||||
* one trace : tr(ql*adj(gIn)*g5*adj(qbl)*g5*G*qbr*gOut*g5*adj(qr)*g5*G)
|
||||
* two traces: tr(ql*adj(gIn)*g5*adj(qbl)*g5*G)*tr(qbr*gOut*g5*adj(qr)*g5*G)
|
||||
*
|
||||
*/
|
||||
|
||||
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||
|
||||
class WeakNonEye3ptPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(WeakNonEye3ptPar,
|
||||
std::string, qLeft,
|
||||
std::string, qBarLeft,
|
||||
std::string, qRight,
|
||||
std::string, qBarRight,
|
||||
Gamma::Algebra, gammaIn,
|
||||
Gamma::Algebra, gammaOut,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TWeakNonEye3pt: public Module<WeakNonEye3ptPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
class Metadata: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Metadata,
|
||||
Gamma::Algebra, in,
|
||||
Gamma::Algebra, out,
|
||||
Gamma::Algebra, op,
|
||||
unsigned int, trace);
|
||||
};
|
||||
typedef Correlator<Metadata> Result;
|
||||
public:
|
||||
// constructor
|
||||
TWeakNonEye3pt(const std::string name);
|
||||
// destructor
|
||||
virtual ~TWeakNonEye3pt(void) {};
|
||||
// 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_TMP(WeakNonEye3pt, TWeakNonEye3pt<FIMPL>, MContraction);
|
||||
|
||||
/******************************************************************************
|
||||
* TWeakNonEye3pt implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TWeakNonEye3pt<FImpl>::TWeakNonEye3pt(const std::string name)
|
||||
: Module<WeakNonEye3ptPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TWeakNonEye3pt<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().qLeft, par().qBarLeft,
|
||||
par().qRight, par().qBarRight};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TWeakNonEye3pt<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TWeakNonEye3pt<FImpl>::setup(void)
|
||||
{
|
||||
envTmpLat(ComplexField, "corr");
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TWeakNonEye3pt<FImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Computing mesonic weak 3pt contractions, non-eye topologies" << std::endl;
|
||||
LOG(Message) << "gIn : " << par().gammaIn << std::endl;
|
||||
LOG(Message) << "gOut: " << par().gammaIn << std::endl;
|
||||
LOG(Message) << "ql : " << par().qLeft << std::endl;
|
||||
LOG(Message) << "qbl : " << par().qBarLeft << std::endl;
|
||||
LOG(Message) << "qr : " << par().qRight << std::endl;
|
||||
LOG(Message) << "qbr : " << par().qBarRight << std::endl;
|
||||
|
||||
std::vector<Result> result;
|
||||
Result r;
|
||||
auto &ql = envGet(PropagatorField, par().qLeft);
|
||||
auto &qbl = envGet(PropagatorField, par().qBarLeft);
|
||||
auto &qr = envGet(PropagatorField, par().qRight);
|
||||
auto &qbr = envGet(PropagatorField, par().qBarRight);
|
||||
Gamma gIn(par().gammaIn), gOut(par().gammaOut);
|
||||
Gamma g5(Gamma::Algebra::Gamma5);
|
||||
|
||||
envGetTmp(ComplexField, corr);
|
||||
r.info.in = par().gammaIn;
|
||||
r.info.out = par().gammaOut;
|
||||
for (auto &G: Gamma::gall)
|
||||
{
|
||||
SlicedComplex buf;
|
||||
|
||||
r.info.op = G.g;
|
||||
// one trace
|
||||
corr = trace(ql*adj(gIn)*g5*adj(qbl)*g5*G*qbr*gOut*g5*adj(qr)*g5*G);
|
||||
sliceSum(corr, buf, Tp);
|
||||
r.corr.clear();
|
||||
for (unsigned int t = 0; t < buf.size(); ++t)
|
||||
{
|
||||
r.corr.push_back(TensorRemove(buf[t]));
|
||||
}
|
||||
r.info.trace = 1;
|
||||
result.push_back(r);
|
||||
// two traces
|
||||
corr = trace(ql*adj(gIn)*g5*adj(qbl)*g5*G)*trace(qbr*gOut*g5*adj(qr)*g5*G);
|
||||
sliceSum(corr, buf, Tp);
|
||||
r.corr.clear();
|
||||
for (unsigned int t = 0; t < buf.size(); ++t)
|
||||
{
|
||||
r.corr.push_back(TensorRemove(buf[t]));
|
||||
}
|
||||
r.info.trace = 2;
|
||||
result.push_back(r);
|
||||
}
|
||||
saveResult(par().output, "weakNonEye3pt", result);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MContraction_WeakNonEye3pt_hpp_
|
@ -1,35 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MFermion/EMLepton.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Hadrons/Modules/MFermion/EMLepton.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MFermion;
|
||||
|
||||
template class Grid::Hadrons::MFermion::TEMLepton<FIMPL>;
|
||||
|
@ -1,315 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MFermion/EMLepton.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Vera Guelpers <Vera.Guelpers@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_MFermion_EMLepton_hpp_
|
||||
#define Hadrons_MFermion_EMLepton_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Calculates a free lepton propagator with a sequential insertion of
|
||||
* i*\gamma_mu A_mu with a photon field A_mu
|
||||
*
|
||||
* L(x) = \sum_y S(x,y) i*\gamma_mu*A_mu S(y,xl) \delta_{(tl-x0),dt}
|
||||
*
|
||||
* with a wall source for the lepton at tl
|
||||
*
|
||||
* In addition outputs the propagator without photon vertex
|
||||
*
|
||||
* L^{free}(x) = S(x,xl) \delta_{(tl-x0),dt}
|
||||
*
|
||||
*
|
||||
* options:
|
||||
* - action: fermion action used for propagator (string)
|
||||
* - emField: photon field A_mu (string)
|
||||
* - mass: input mass for the lepton propagator
|
||||
* - boundary: boundary conditions for the lepton propagator, e.g. "1 1 1 -1"
|
||||
* - twist: twisted boundary for lepton propagator, e.g. "0.0 0.0 0.0 0.5"
|
||||
* - deltat: list of source-sink separations
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* EMLepton *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MFermion)
|
||||
|
||||
class EMLeptonPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(EMLeptonPar,
|
||||
std::string, action,
|
||||
std::string, emField,
|
||||
double, mass,
|
||||
std::string , boundary,
|
||||
std::string, twist,
|
||||
std::vector<unsigned int>, deltat);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TEMLepton: public Module<EMLeptonPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
typedef PhotonR::GaugeField EmField;
|
||||
public:
|
||||
// constructor
|
||||
TEMLepton(const std::string name);
|
||||
// destructor
|
||||
virtual ~TEMLepton(void) {};
|
||||
// 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_TMP(EMLepton, TEMLepton<FIMPL>, MFermion);
|
||||
|
||||
/******************************************************************************
|
||||
* TEMLepton implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TEMLepton<FImpl>::TEMLepton(const std::string name)
|
||||
: Module<EMLeptonPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TEMLepton<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().action, par().emField};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TEMLepton<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {};
|
||||
for(int i=0; i<par().deltat.size(); i++)
|
||||
{
|
||||
out.push_back(std::to_string(par().deltat[i]) + "_" + getName() + "_free");
|
||||
out.push_back(std::to_string(par().deltat[i]) + "_" + getName());
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TEMLepton<FImpl>::setup(void)
|
||||
{
|
||||
Ls_ = env().getObjectLs(par().action);
|
||||
for(int i=0; i<par().deltat.size(); i++)
|
||||
{
|
||||
envCreateLat(PropagatorField, std::to_string(par().deltat[i]) + "_" + getName() + "_free");
|
||||
envCreateLat(PropagatorField, std::to_string(par().deltat[i]) + "_" + getName());
|
||||
}
|
||||
envTmpLat(FermionField, "source", Ls_);
|
||||
envTmpLat(FermionField, "sol", Ls_);
|
||||
envTmpLat(FermionField, "tmp");
|
||||
envTmpLat(PropagatorField, "sourcetmp");
|
||||
envTmpLat(PropagatorField, "proptmp");
|
||||
envTmpLat(PropagatorField, "freetmp");
|
||||
envTmp(Lattice<iScalar<vInteger>>, "tlat",1, envGetGrid(LatticeComplex));
|
||||
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TEMLepton<FImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Computing free fermion propagator '" << getName() << "'"
|
||||
<< std::endl;
|
||||
|
||||
auto &mat = envGet(FMat, par().action);
|
||||
RealD mass = par().mass;
|
||||
Complex ci(0.0,1.0);
|
||||
|
||||
envGetTmp(FermionField, source);
|
||||
envGetTmp(FermionField, sol);
|
||||
envGetTmp(FermionField, tmp);
|
||||
LOG(Message) << "Calculating a lepton Propagator with sequential Aslash insertion with lepton mass "
|
||||
<< mass << " using the action '" << par().action
|
||||
<< "' for fixed source-sink separation of " << par().deltat << std::endl;
|
||||
|
||||
envGetTmp(Lattice<iScalar<vInteger>>, tlat);
|
||||
LatticeCoordinate(tlat, Tp);
|
||||
|
||||
|
||||
std::vector<double> twist = strToVec<double>(par().twist);
|
||||
if(twist.size() != Nd)
|
||||
{
|
||||
HADRONS_ERROR(Size, "number of twist angles does not match number of dimensions");
|
||||
}
|
||||
std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
|
||||
if(boundary.size() != Nd)
|
||||
{
|
||||
HADRONS_ERROR(Size, "number of boundary conditions does not match number of dimensions");
|
||||
}
|
||||
|
||||
auto &stoch_photon = envGet(EmField, par().emField);
|
||||
unsigned int nt = env().getDim(Tp);
|
||||
|
||||
envGetTmp(PropagatorField, proptmp);
|
||||
envGetTmp(PropagatorField, freetmp);
|
||||
envGetTmp(PropagatorField, sourcetmp);
|
||||
|
||||
std::vector<int> position;
|
||||
SitePropagator id;
|
||||
id = 1.;
|
||||
|
||||
unsigned int tl=0;
|
||||
|
||||
//wallsource at tl
|
||||
sourcetmp = 1.;
|
||||
sourcetmp = where((tlat == tl), sourcetmp, 0.*sourcetmp);
|
||||
|
||||
//free propagator from pt source
|
||||
for (unsigned int s = 0; s < Ns; ++s)
|
||||
{
|
||||
LOG(Message) << "Calculation for spin= " << s << std::endl;
|
||||
if (Ls_ == 1)
|
||||
{
|
||||
PropToFerm<FImpl>(source, sourcetmp, s, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropToFerm<FImpl>(tmp, sourcetmp, s, 0);
|
||||
// 5D source if action is 5d
|
||||
mat.ImportPhysicalFermionSource(tmp, source);
|
||||
}
|
||||
sol = zero;
|
||||
mat.FreePropagator(source,sol,mass,boundary,twist);
|
||||
if (Ls_ == 1)
|
||||
{
|
||||
FermToProp<FImpl>(freetmp, sol, s, 0);
|
||||
}
|
||||
// create 4D propagators from 5D one if necessary
|
||||
if (Ls_ > 1)
|
||||
{
|
||||
mat.ExportPhysicalFermionSolution(sol, tmp);
|
||||
FermToProp<FImpl>(freetmp, tmp, s, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int dt=0;dt<par().deltat.size();dt++){
|
||||
PropagatorField &lep = envGet(PropagatorField, std::to_string(par().deltat[dt]) + "_" + getName() + "_free");
|
||||
for(tl=0;tl<nt;tl++){
|
||||
|
||||
//shift free propagator to different source positions
|
||||
//account for possible anti-periodic boundary in time
|
||||
proptmp = Cshift(freetmp,Tp, -tl);
|
||||
proptmp = where( tlat < tl, boundary[Tp]*proptmp, proptmp);
|
||||
|
||||
// free propagator for fixed source-sink separation
|
||||
lep = where(tlat == (tl-par().deltat[dt]+nt)%nt, proptmp, lep);
|
||||
}
|
||||
//account for possible anti-periodic boundary in time
|
||||
lep = where( tlat >= nt-par().deltat[dt], boundary[Tp]*lep, lep);
|
||||
}
|
||||
|
||||
for(tl=0;tl<nt;tl++){
|
||||
|
||||
//shift free propagator to different source positions
|
||||
//account for possible anti-periodic boundary in time
|
||||
proptmp = Cshift(freetmp,Tp, -tl);
|
||||
proptmp = where( tlat < tl, boundary[Tp]*proptmp, proptmp);
|
||||
|
||||
// i*A_mu*gamma_mu
|
||||
sourcetmp = zero;
|
||||
for(unsigned int mu=0;mu<=3;mu++)
|
||||
{
|
||||
Gamma gmu(Gamma::gmu[mu]);
|
||||
sourcetmp += ci * PeekIndex<LorentzIndex>(stoch_photon, mu) * (gmu * proptmp );
|
||||
}
|
||||
|
||||
proptmp = zero;
|
||||
|
||||
//sequential propagator from i*Aslash*S
|
||||
LOG(Message) << "Sequential propagator for t= " << tl << std::endl;
|
||||
for (unsigned int s = 0; s < Ns; ++s)
|
||||
{
|
||||
LOG(Message) << "Calculation for spin= " << s << std::endl;
|
||||
if (Ls_ == 1)
|
||||
{
|
||||
PropToFerm<FImpl>(source, sourcetmp, s, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropToFerm<FImpl>(tmp, sourcetmp, s, 0);
|
||||
// 5D source if action is 5d
|
||||
mat.ImportPhysicalFermionSource(tmp, source);
|
||||
}
|
||||
sol = zero;
|
||||
mat.FreePropagator(source,sol,mass,boundary,twist);
|
||||
if (Ls_ == 1)
|
||||
{
|
||||
FermToProp<FImpl>(proptmp, sol, s, 0);
|
||||
}
|
||||
// create 4D propagators from 5D one if necessary
|
||||
if (Ls_ > 1)
|
||||
{
|
||||
mat.ExportPhysicalFermionSolution(sol, tmp);
|
||||
FermToProp<FImpl>(proptmp, tmp, s, 0);
|
||||
}
|
||||
}
|
||||
// keep the result for the desired delta t
|
||||
for(unsigned int dt=0;dt<par().deltat.size();dt++){
|
||||
PropagatorField &Aslashlep = envGet(PropagatorField, std::to_string(par().deltat[dt]) + "_" + getName());
|
||||
Aslashlep = where(tlat == (tl-par().deltat[dt]+nt)%nt, proptmp, Aslashlep);
|
||||
}
|
||||
}
|
||||
|
||||
//account for possible anti-periodic boundary in time
|
||||
for(unsigned int dt=0;dt<par().deltat.size();dt++){
|
||||
PropagatorField &Aslashlep = envGet(PropagatorField, std::to_string(par().deltat[dt]) + "_" + getName());
|
||||
Aslashlep = where( tlat >= nt-par().deltat[dt], boundary[Tp]*Aslashlep, Aslashlep);
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MFermion_EMLepton_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/Electrify.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
Author: Vera Guelpers <vmg1n14@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 <Hadrons/Modules/MGauge/Electrify.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MGauge;
|
||||
|
||||
template class Grid::Hadrons::MGauge::TElectrify<GIMPL>;
|
@ -1,153 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/Electrify.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
Author: Vera Guelpers <vmg1n14@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 */
|
||||
|
||||
#ifndef Hadrons_MGauge_Electrify_hpp_
|
||||
#define Hadrons_MGauge_Electrify_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Electrify gauge *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MGauge)
|
||||
|
||||
/****************************************************************************
|
||||
* Electrify a gauge field:
|
||||
*
|
||||
* Ue_mu(x) = U_mu(x)*exp(ieqA_mu(x))
|
||||
*
|
||||
* with
|
||||
*
|
||||
* - gauge: U_mu(x): gauge field
|
||||
* - emField: A_mu(x): electromagnetic photon field
|
||||
* - e: value for the elementary charge
|
||||
* - q: charge in units of e
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
class ElectrifyPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(ElectrifyPar,
|
||||
std::string, gauge,
|
||||
std::string, emField,
|
||||
double, e,
|
||||
double, charge);
|
||||
};
|
||||
|
||||
template <typename GImpl>
|
||||
class TElectrify: public Module<ElectrifyPar>
|
||||
{
|
||||
public:
|
||||
GAUGE_TYPE_ALIASES(GImpl,);
|
||||
public:
|
||||
typedef PhotonR::GaugeField EmField;
|
||||
public:
|
||||
// constructor
|
||||
TElectrify(const std::string name);
|
||||
// destructor
|
||||
virtual ~TElectrify(void) {};
|
||||
// dependencies/products
|
||||
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_TMP(Electrify, TElectrify<GIMPL>, MGauge);
|
||||
|
||||
/******************************************************************************
|
||||
* TElectrify implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
TElectrify<GImpl>::TElectrify(const std::string name)
|
||||
: Module<ElectrifyPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
std::vector<std::string> TElectrify<GImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().gauge, par().emField};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename GImpl>
|
||||
std::vector<std::string> TElectrify<GImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
void TElectrify<GImpl>::setup(void)
|
||||
{
|
||||
envCreateLat(GaugeField, getName());
|
||||
envTmpLat(LatticeComplex, "eiAmu");
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
void TElectrify<GImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Electrify the gauge field " << par().gauge << " using the photon field "
|
||||
<< par().emField << " with charge e*q= " << par().e << "*" << par().charge << std::endl;
|
||||
|
||||
auto &Ue = envGet(GaugeField, getName());
|
||||
auto &U = envGet(GaugeField, par().gauge);
|
||||
auto &A = envGet(EmField, par().emField);
|
||||
envGetTmp(LatticeComplex, eiAmu);
|
||||
|
||||
Complex i(0.0,1.0);
|
||||
|
||||
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
||||
{
|
||||
eiAmu = exp(i * (Real)(par().e * par().charge) * PeekIndex<LorentzIndex>(A, mu));
|
||||
PokeIndex<LorentzIndex>(Ue, PeekIndex<LorentzIndex>(U, mu) * eiAmu, mu);
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MGauge_Electrify_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/GaugeFix.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 */
|
||||
|
||||
#include <Hadrons/Modules/MGauge/GaugeFix.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MGauge;
|
||||
|
||||
template class Grid::Hadrons::MGauge::TGaugeFix<GIMPL>;
|
@ -1,143 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/GaugeFix.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Nils Asmussen <n.asmussen@soton.ac.uk>
|
||||
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 Hadrons_MGaugeFix_hpp_
|
||||
#define Hadrons_MGaugeFix_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Grid/qcd/utils/GaugeFix.h>
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Fix gauge *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MGauge)
|
||||
|
||||
GRID_SERIALIZABLE_ENUM(Fix, undef, coulomb, Nd - 1, landau, -1);
|
||||
|
||||
class GaugeFixPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(GaugeFixPar,
|
||||
std::string, gauge,
|
||||
Real, alpha,
|
||||
int, maxiter,
|
||||
Real, Omega_tol,
|
||||
Real, Phi_tol,
|
||||
Fix, gaugeFix,
|
||||
bool, Fourier);
|
||||
};
|
||||
|
||||
template <typename GImpl>
|
||||
class TGaugeFix: public Module<GaugeFixPar>
|
||||
{
|
||||
public:
|
||||
GAUGE_TYPE_ALIASES(GImpl,);
|
||||
typedef typename GImpl::GaugeLinkField GaugeMat;
|
||||
public:
|
||||
// constructor
|
||||
TGaugeFix(const std::string name);
|
||||
// destructor
|
||||
virtual ~TGaugeFix(void) {};
|
||||
// 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_TMP(GaugeFix, TGaugeFix<GIMPL>, MGauge);
|
||||
|
||||
/******************************************************************************
|
||||
* TGaugeFix implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
TGaugeFix<GImpl>::TGaugeFix(const std::string name)
|
||||
: Module<GaugeFixPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
std::vector<std::string> TGaugeFix<GImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().gauge};
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename GImpl>
|
||||
std::vector<std::string> TGaugeFix<GImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName(), getName()+"_xform"};
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
void TGaugeFix<GImpl>::setup(void)
|
||||
{
|
||||
envCreateLat(GaugeField, getName());
|
||||
envCreateLat(GaugeMat, getName()+"_xform");
|
||||
}
|
||||
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename GImpl>
|
||||
void TGaugeFix<GImpl>::execute(void)
|
||||
//Loads the gauge and fixes it
|
||||
{
|
||||
std::cout << "executing" << std::endl;
|
||||
LOG(Message) << "Fixing the Gauge " << par().gauge << " using "
|
||||
<< par().gaugeFix << " guage fixing. " << Nd - 1 << std::endl;
|
||||
auto &U = envGet(GaugeField, par().gauge);
|
||||
auto &Umu = envGet(GaugeField, getName());
|
||||
auto &xform = envGet(GaugeMat, getName()+"_xform");
|
||||
LOG(Message) << "Gauge Field fetched" << std::endl;
|
||||
//do we allow maxiter etc to be user set?
|
||||
Real alpha = par().alpha;
|
||||
int maxiter = par().maxiter;
|
||||
Real Omega_tol = par().Omega_tol;
|
||||
Real Phi_tol = par().Phi_tol;
|
||||
int gaugeFix = par().gaugeFix;
|
||||
bool Fourier = par().Fourier;
|
||||
Umu = U;
|
||||
FourierAcceleratedGaugeFixer<PeriodicGimplR>::SteepestDescentGaugeFix(Umu,xform,alpha,maxiter,Omega_tol,Phi_tol,Fourier,gaugeFix);
|
||||
LOG(Message) << "Gauge Fixed" << std::endl;
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MGaugeFix_hpp_
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/Random.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MGauge/Random.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MGauge;
|
||||
|
||||
template class Grid::Hadrons::MGauge::TRandom<GIMPL>;
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/StoutSmearing.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MGauge/StoutSmearing.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MGauge;
|
||||
|
||||
template class Grid::Hadrons::MGauge::TStoutSmearing<GIMPL>;
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MGauge/Unit.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MGauge/Unit.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MGauge;
|
||||
|
||||
template class Grid::Hadrons::MGauge::TUnit<GIMPL>;
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MIO/LoadA2AVectors.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MIO/LoadA2AVectors.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MIO;
|
||||
|
||||
template class Grid::Hadrons::MIO::TLoadA2AVectors<FIMPL>;
|
@ -1,38 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MIO/LoadCosmHol.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MIO/LoadCosmHol.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MIO;
|
||||
|
||||
template class Grid::Hadrons::MIO::TLoadCosmHol<ScalarNxNAdjImplR<2>>;
|
||||
template class Grid::Hadrons::MIO::TLoadCosmHol<ScalarNxNAdjImplR<3>>;
|
||||
template class Grid::Hadrons::MIO::TLoadCosmHol<ScalarNxNAdjImplR<4>>;
|
||||
template class Grid::Hadrons::MIO::TLoadCosmHol<ScalarNxNAdjImplR<5>>;
|
||||
template class Grid::Hadrons::MIO::TLoadCosmHol<ScalarNxNAdjImplR<6>>;
|
@ -1,146 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MIO/LoadCosmHol.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_LoadCosmHol_hpp_
|
||||
#define Hadrons_MIO_LoadCosmHol_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Load scalar SU(N) configurations *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MIO)
|
||||
|
||||
class LoadCosmHolPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LoadCosmHolPar,
|
||||
std::string, file);
|
||||
};
|
||||
|
||||
class ScalarActionParameters: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(ScalarActionParameters,
|
||||
double, mass_squared,
|
||||
double, lambda,
|
||||
double, g);
|
||||
};
|
||||
|
||||
template <typename SImpl>
|
||||
class TLoadCosmHol: public Module<LoadCosmHolPar>
|
||||
{
|
||||
public:
|
||||
typedef typename SImpl::Field Field;
|
||||
public:
|
||||
// constructor
|
||||
TLoadCosmHol(const std::string name);
|
||||
// destructor
|
||||
virtual ~TLoadCosmHol(void) {};
|
||||
// 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_TMP(LoadCosmHolSU2, TLoadCosmHol<ScalarNxNAdjImplR<2>>, MIO);
|
||||
MODULE_REGISTER_TMP(LoadCosmHolSU3, TLoadCosmHol<ScalarNxNAdjImplR<3>>, MIO);
|
||||
MODULE_REGISTER_TMP(LoadCosmHolSU4, TLoadCosmHol<ScalarNxNAdjImplR<4>>, MIO);
|
||||
MODULE_REGISTER_TMP(LoadCosmHolSU5, TLoadCosmHol<ScalarNxNAdjImplR<5>>, MIO);
|
||||
MODULE_REGISTER_TMP(LoadCosmHolSU6, TLoadCosmHol<ScalarNxNAdjImplR<6>>, MIO);
|
||||
|
||||
/******************************************************************************
|
||||
* TLoadCosmHol implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename SImpl>
|
||||
TLoadCosmHol<SImpl>::TLoadCosmHol(const std::string name)
|
||||
: Module<LoadCosmHolPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename SImpl>
|
||||
std::vector<std::string> TLoadCosmHol<SImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename SImpl>
|
||||
std::vector<std::string> TLoadCosmHol<SImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename SImpl>
|
||||
void TLoadCosmHol<SImpl>::setup(void)
|
||||
{
|
||||
envCreateLat(Field, getName());
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename SImpl>
|
||||
void TLoadCosmHol<SImpl>::execute(void)
|
||||
{
|
||||
ScalarActionParameters md;
|
||||
std::string filename = par().file + "."
|
||||
+ std::to_string(vm().getTrajectory());
|
||||
ScidacReader reader;
|
||||
const unsigned int N = SImpl::Group::Dimension;
|
||||
auto &phi = envGet(Field, getName());
|
||||
|
||||
LOG(Message) << "Loading CosmHol configuration from file '" << filename
|
||||
<< "'" << std::endl;
|
||||
reader.open(filename);
|
||||
reader.readScidacFieldRecord(phi, md);
|
||||
reader.close();
|
||||
LOG(Message) << "tr(phi^2) = "
|
||||
<< -TensorRemove(sum(trace(phi*phi))).real()/env().getVolume()
|
||||
<< std::endl;
|
||||
LOG(Message) << "Configuration parameters:" << std::endl;
|
||||
LOG(Message) << " N = " << N << std::endl;
|
||||
LOG(Message) << " m^2 = " << md.mass_squared << std::endl;
|
||||
LOG(Message) << "lambda = " << md.lambda << std::endl;
|
||||
LOG(Message) << " g = " << md.g << std::endl;
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MIO_LoadCosmHol_hpp_
|
@ -1,191 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MIO/LoadEigenPack.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_LoadEigenPack_hpp_
|
||||
#define Hadrons_MIO_LoadEigenPack_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/EigenPack.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Load eigen vectors/values package *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MIO)
|
||||
|
||||
class LoadEigenPackPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(LoadEigenPackPar,
|
||||
std::string, filestem,
|
||||
bool, multiFile,
|
||||
unsigned int, size,
|
||||
unsigned int, Ls,
|
||||
std::string, gaugeXform);
|
||||
};
|
||||
|
||||
template <typename Pack, typename GImpl>
|
||||
class TLoadEigenPack: public Module<LoadEigenPackPar>
|
||||
{
|
||||
public:
|
||||
typedef typename Pack::Field Field;
|
||||
typedef typename Pack::FieldIo FieldIo;
|
||||
typedef BaseEigenPack<Field> BasePack;
|
||||
|
||||
public:
|
||||
GAUGE_TYPE_ALIASES(GImpl, );
|
||||
typedef typename GImpl::GaugeLinkField GaugeMat;
|
||||
public:
|
||||
// constructor
|
||||
TLoadEigenPack(const std::string name);
|
||||
// destructor
|
||||
virtual ~TLoadEigenPack(void) {};
|
||||
// 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_TMP(LoadFermionEigenPack, ARG(TLoadEigenPack<FermionEigenPack<FIMPL>, GIMPL>), MIO);
|
||||
#ifdef GRID_DEFAULT_PRECISION_DOUBLE
|
||||
MODULE_REGISTER_TMP(LoadFermionEigenPackIo32, ARG(TLoadEigenPack<FermionEigenPack<FIMPL, FIMPLF>, GIMPL>), MIO);
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* TLoadEigenPack implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename Pack, typename GImpl>
|
||||
TLoadEigenPack<Pack, GImpl>::TLoadEigenPack(const std::string name)
|
||||
: Module<LoadEigenPackPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename Pack, typename GImpl>
|
||||
std::vector<std::string> TLoadEigenPack<Pack, GImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
if (!par().gaugeXform.empty())
|
||||
{
|
||||
in = {par().gaugeXform};
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename Pack, typename GImpl>
|
||||
std::vector<std::string> TLoadEigenPack<Pack, GImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename Pack, typename GImpl>
|
||||
void TLoadEigenPack<Pack, GImpl>::setup(void)
|
||||
{
|
||||
GridBase *gridIo = nullptr;
|
||||
|
||||
if (typeHash<Field>() != typeHash<FieldIo>())
|
||||
{
|
||||
gridIo = envGetRbGrid(FieldIo, par().Ls);
|
||||
}
|
||||
envCreateDerived(BasePack, Pack, getName(), par().Ls, par().size,
|
||||
envGetRbGrid(Field, par().Ls), gridIo);
|
||||
|
||||
if (!par().gaugeXform.empty())
|
||||
{
|
||||
if (par().Ls > 1)
|
||||
{
|
||||
LOG(Message) << "Setup 5d GaugeMat for Ls = " << par().Ls << std::endl;
|
||||
envTmp(GaugeMat, "tmpXform", par().Ls, envGetGrid5(Field, par().Ls));
|
||||
envTmp(GaugeMat, "tmpXformOdd", par().Ls, envGetRbGrid5(Field, par().Ls));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Message) << "Setup 4d GaugeMat for Ls = " << par().Ls << std::endl;
|
||||
envTmp(GaugeMat, "tmpXform", par().Ls, envGetGrid(Field));
|
||||
envTmp(GaugeMat, "tmpXformOdd", par().Ls, envGetRbGrid(Field));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename Pack, typename GImpl>
|
||||
void TLoadEigenPack<Pack, GImpl>::execute(void)
|
||||
{
|
||||
auto &epack = envGetDerived(BasePack, Pack, getName());
|
||||
|
||||
epack.read(par().filestem, par().multiFile, vm().getTrajectory());
|
||||
epack.eval.resize(par().size);
|
||||
|
||||
if (!par().gaugeXform.empty())
|
||||
{
|
||||
|
||||
LOG(Message) << "Applying gauge transformation to eigenvectors " << getName()
|
||||
<< " using " << par().gaugeXform << std::endl;
|
||||
auto &xform = envGet(GaugeMat, par().gaugeXform);
|
||||
envGetTmp(GaugeMat, tmpXform);
|
||||
envGetTmp(GaugeMat, tmpXformOdd);
|
||||
|
||||
if (par().Ls > 1)
|
||||
{
|
||||
LOG(Message) << "Creating 5d GaugeMat from " << par().gaugeXform << std::endl;
|
||||
startTimer("5-d gauge transform creation");
|
||||
for (unsigned int j = 0; j < par().Ls; j++)
|
||||
{
|
||||
InsertSlice(xform, tmpXform, j, 0);
|
||||
}
|
||||
stopTimer("5-d gauge transform creation");
|
||||
}
|
||||
|
||||
pickCheckerboard(Odd, tmpXformOdd, tmpXform);
|
||||
startTimer("Transform application");
|
||||
for (unsigned int i = 0; i < par().size; i++)
|
||||
{
|
||||
LOG(Message) << "Applying gauge transformation to eigenvector i = " << i << "/" << par().size << std::endl;
|
||||
epack.evec[i].checkerboard = Odd;
|
||||
epack.evec[i] = tmpXformOdd * epack.evec[i];
|
||||
}
|
||||
stopTimer("Transform application");
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MIO_LoadEigenPack_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNPR/Amputate.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 */
|
||||
#include <Hadrons/Modules/MNPR/Amputate.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MNPR;
|
||||
|
||||
template class Grid::Hadrons::MNPR::TAmputate<FIMPL,FIMPL>;
|
||||
|
@ -1,200 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNPR/Amputate.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Julia Kettle J.R.Kettle-2@sms.ed.ac.uk
|
||||
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 Hadrons_Amputate_hpp_
|
||||
#define Hadrons_Amputate_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Grid/Eigen/LU>
|
||||
//#include <Grid/qcd/utils/PropagatorUtils.h>
|
||||
//#include <Grid/serialisation/Serialisation.h>
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* TAmputate *
|
||||
Performs bilinear contractions of the type tr[g5*adj(Sout)*g5*G*Sin]
|
||||
Suitable for non exceptional momenta
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MNPR)
|
||||
|
||||
class AmputatePar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(AmputatePar,
|
||||
std::string, Sin, //need to make this a propogator type?
|
||||
std::string, Sout, //same
|
||||
std::string, vertex,
|
||||
std::string, pin,
|
||||
std::string, pout,
|
||||
std::string, output,
|
||||
std::string, input);
|
||||
};
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
class TAmputate: public Module<AmputatePar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl1, 1);
|
||||
FERM_TYPE_ALIASES(FImpl2, 2);
|
||||
class Result: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||
std::vector<Complex>, Vamp,
|
||||
);
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
TAmputate(const std::string name);
|
||||
// destructor
|
||||
virtual ~TAmputate(void) {};
|
||||
// dependencies/products
|
||||
virtual std::vector<std::string> getInput(void);
|
||||
virtual std::vector<std::string> getOutput(void);
|
||||
virtual SpinColourMatrix invertspincolmat(SpinColourMatrix &scmat);
|
||||
// execution
|
||||
virtual void execute(void);
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(Amputate, ARG(TAmputate<FIMPL, FIMPL>), MNPR);
|
||||
|
||||
/******************************************************************************
|
||||
* TAmputate implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
TAmputate<FImpl1, FImpl2>::TAmputate(const std::string name)
|
||||
: Module<AmputatePar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
std::vector<std::string> TAmputate<FImpl1, FImpl2>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> input = {par().Sin, par().Sout, par().vertex};
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
std::vector<std::string> TAmputate<FImpl1, FImpl2>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> output = {getName()};
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Invert spin colour matrix using Eigen
|
||||
template <typename Fimpl1, typename Fimpl2>
|
||||
SpinColourMatrix TAmputate<Fimpl1, Fimpl2>::invertspincolmat(SpinColourMatrix &scmat)
|
||||
{
|
||||
Eigen::MatrixXcf scmat_2d(Ns*Nc,Ns*Nc);
|
||||
for(int ic=0; ic<Nc; ic++){
|
||||
for(int jc=0; jc<Nc; jc++){
|
||||
for(int is=0; is<Ns; is++){
|
||||
for(int js=0; js<Ns; js++){
|
||||
scmat_2d(Ns*ic+is,Ns*jc+js) = scmat()(is,js)(ic,jc);
|
||||
}}
|
||||
}}
|
||||
Eigen::MatrixXcf scmat_2d_inv = scmat_2d.inverse();
|
||||
SpinColourMatrix scmat_inv;
|
||||
for(int ic=0; ic<Nc; ic++){
|
||||
for(int jc=0; jc<Nc; jc++){
|
||||
for(int is=0; is<Ns; is++){
|
||||
for(int js=0; js<Ns; js++){
|
||||
scmat_inv()(is,js)(ic,jc) = scmat_2d_inv(Ns*ic+is,Ns*jc+js);
|
||||
}}
|
||||
}}
|
||||
return scmat_inv;
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
void TAmputate<FImpl1, FImpl2>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Computing bilinear amputations '" << getName() << "' using"
|
||||
<< " momentum '" << par().Sin << "' and '" << par().Sout << "'"
|
||||
<< std::endl;
|
||||
BinaryWriter writer(par().output);
|
||||
PropagatorField1 &Sin = *env().template getObject<PropagatorField1>(par().Sin); //Do these have the phases taken into account?? Don't think so. FIX
|
||||
PropagatorField2 &Sout = *env().template getObject<PropagatorField2>(par().Sout);
|
||||
std::vector<int> pin = strToVec<int>(par().pin), pout = strToVec<int>(par().pout);
|
||||
std::vector<Real> latt_size(pin.begin(), pin.end());
|
||||
LatticeComplex pdotxin(env().getGrid()), pdotxout(env().getGrid()), coor(env().getGrid());
|
||||
LOG(Message) << "Propagators set up " << std::endl;
|
||||
std::vector<SpinColourMatrix> vertex; // Let's read from file here
|
||||
Gamma g5(Gamma::Algebra::Gamma5);
|
||||
Result result;
|
||||
LOG(Message) << "reading file - " << par().input << std::endl;
|
||||
BinaryReader reader(par().input);
|
||||
Complex Ci(0.0,1.0);
|
||||
|
||||
std::string svertex;
|
||||
read(reader,"vertex", vertex);
|
||||
LOG(Message) << "vertex read" << std::endl;
|
||||
|
||||
pdotxin=zero;
|
||||
pdotxout=zero;
|
||||
for (unsigned int mu = 0; mu < 4; ++mu)
|
||||
{
|
||||
Real TwoPiL = M_PI * 2.0/ latt_size[mu];
|
||||
LatticeCoordinate(coor,mu);
|
||||
pdotxin = pdotxin +(TwoPiL * pin[mu]) * coor;
|
||||
pdotxout= pdotxout +(TwoPiL * pout[mu]) * coor;
|
||||
}
|
||||
Sin = Sin*exp(-Ci*pdotxin); //phase corrections
|
||||
Sout = Sout*exp(-Ci*pdotxout);
|
||||
|
||||
SpinColourMatrix Sin_mom = sum(Sin);
|
||||
SpinColourMatrix Sout_mom = sum(Sout);
|
||||
LOG(Message) << "summed over lattice" << std::endl;
|
||||
|
||||
LOG(Message) << "Lattice -> spincolourmatrix conversion" << std::endl;
|
||||
|
||||
SpinColourMatrix Sin_inv = invertspincolmat(Sin_mom);
|
||||
SpinColourMatrix Sout_inv = invertspincolmat(Sout_mom);
|
||||
LOG(Message) << "Inversions done" << std::endl;
|
||||
|
||||
result.Vamp.resize(Gamma::nGamma/2);
|
||||
for( int mu=0; mu < Gamma::nGamma/2; mu++){
|
||||
Gamma::Algebra gam = mu;
|
||||
result.Vamp[mu] = 1/12.0*trace(adj(Gamma(mu*2+1))*g5*Sout_inv*g5*vertex[mu]*Sin_inv);
|
||||
LOG(Message) << "Vamp[" << mu << "] - " << result.Vamp[mu] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_Amputate_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNPR/Bilinear.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 */
|
||||
#include <Hadrons/Modules/MNPR/Bilinear.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MNPR;
|
||||
|
||||
template class Grid::Hadrons::MNPR::TBilinear<FIMPL,FIMPL>;
|
||||
|
@ -1,225 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNPR/Bilinear.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Julia Kettle J.R.Kettle-2@sms.ed.ac.uk
|
||||
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 Hadrons_Bilinear_hpp_
|
||||
#define Hadrons_Bilinear_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
//#include <Grid/qcd/utils/PropagatorUtils.h>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* TBilinear *
|
||||
Performs bilinear contractions of the type tr[g5*adj(Sout)*g5*G*Sin]
|
||||
Suitable for non exceptional momenta in Rome-Southampton NPR
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MNPR)
|
||||
|
||||
class BilinearPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(BilinearPar,
|
||||
std::string, Sin,
|
||||
std::string, Sout,
|
||||
std::string, pin,
|
||||
std::string, pout,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
class TBilinear: public Module<BilinearPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl1, 1);
|
||||
FERM_TYPE_ALIASES(FImpl2, 2);
|
||||
class Result: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||
std::vector<SpinColourMatrix>, bilinear);
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
TBilinear(const std::string name);
|
||||
// destructor
|
||||
virtual ~TBilinear(void) {};
|
||||
// dependencies/products
|
||||
virtual std::vector<std::string> getInput(void);
|
||||
virtual std::vector<std::string> getOutput(void);
|
||||
//LatticeSpinColourMatrix PhaseProps(LatticeSpinColourMatrix S, std::vector<Real> p);
|
||||
// setup
|
||||
virtual void setup(void);
|
||||
// execution
|
||||
virtual void execute(void);
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(Bilinear, ARG(TBilinear<FIMPL, FIMPL>), MNPR);
|
||||
|
||||
/******************************************************************************
|
||||
* TBilinear implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
TBilinear<FImpl1, FImpl2>::TBilinear(const std::string name)
|
||||
: Module<BilinearPar>(name)
|
||||
{}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
void TBilinear<FImpl1, FImpl2>::setup(void)
|
||||
{
|
||||
//env().template registerLattice<LatticeSpinColourMatrix>(getName());
|
||||
//env().template registerObject<SpinColourMatrix>(getName());
|
||||
}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
std::vector<std::string> TBilinear<FImpl1, FImpl2>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> input = {par().Sin, par().Sout};
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
std::vector<std::string> TBilinear<FImpl1, FImpl2>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
/////Phase propagators//////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
LatticeSpinColourMatrix TBilinear<FImpl1, FImpl2>::PhaseProps(LatticeSpinColourMatrix S, std::vector<Real> p)
|
||||
{
|
||||
GridBase *grid = S._grid;
|
||||
LatticeComplex pdotx(grid), coor(grid);
|
||||
std::vector<int> latt_size = grid->_fdimensions;
|
||||
Complex Ci(0.0,1.0);
|
||||
pdotx=zero;
|
||||
for (unsigned int mu = 0; mu < 4; ++mu)
|
||||
{
|
||||
Real TwoPiL = M_PI * 2.0/ latt_size[mu];
|
||||
LatticeCoordinate(coor,mu);
|
||||
pdotx = pdotx +(TwoPiL * p[mu]) * coor;
|
||||
}
|
||||
S = S*exp(-Ci*pdotx);
|
||||
return S;
|
||||
}
|
||||
*/
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
void TBilinear<FImpl1, FImpl2>::execute(void)
|
||||
{
|
||||
/**************************************************************************
|
||||
|
||||
Compute the bilinear vertex needed for the NPR.
|
||||
V(G) = sum_x [ g5 * adj(S'(x,p2)) * g5 * G * S'(x,p1) ]_{si,sj,ci,cj}
|
||||
G is one of the 16 gamma vertices [I,gmu,g5,g5gmu,sig(mu,nu)]
|
||||
|
||||
* G
|
||||
/ \
|
||||
p1/ \p2
|
||||
/ \
|
||||
/ \
|
||||
|
||||
Returns a spin-colour matrix, with indices si,sj, ci,cj
|
||||
|
||||
Conventions:
|
||||
p1 - incoming momenta
|
||||
p2 - outgoing momenta
|
||||
q = (p1-p2)
|
||||
**************************************************************************/
|
||||
|
||||
LOG(Message) << "Computing bilinear contractions '" << getName() << "' using"
|
||||
<< " momentum '" << par().Sin << "' and '" << par().Sout << "'"
|
||||
<< std::endl;
|
||||
|
||||
BinaryWriter writer(par().output);
|
||||
|
||||
|
||||
// Propogators
|
||||
LatticeSpinColourMatrix &Sin = *env().template getObject<LatticeSpinColourMatrix>(par().Sin);
|
||||
LatticeSpinColourMatrix &Sout = *env().template getObject<LatticeSpinColourMatrix>(par().Sout);
|
||||
LatticeComplex pdotxin(env().getGrid()), pdotxout(env().getGrid()), coor(env().getGrid());
|
||||
// momentum on legs
|
||||
std::vector<Real> pin = strToVec<Real>(par().pin), pout = strToVec<Real>(par().pout);
|
||||
std::vector<Real> latt_size(pin.begin(), pin.end());
|
||||
//bilinears
|
||||
LatticeSpinColourMatrix bilinear_x(env().getGrid());
|
||||
SpinColourMatrix bilinear;
|
||||
Gamma g5(Gamma::Algebra::Gamma5);
|
||||
Result result;
|
||||
Complex Ci(0.0,1.0);
|
||||
|
||||
//
|
||||
|
||||
pdotxin=zero;
|
||||
pdotxout=zero;
|
||||
for (unsigned int mu = 0; mu < 4; ++mu)
|
||||
{
|
||||
Real TwoPiL = M_PI * 2.0/ latt_size[mu];
|
||||
LatticeCoordinate(coor,mu);
|
||||
pdotxin = pdotxin +(TwoPiL * pin[mu]) * coor;
|
||||
pdotxout= pdotxout +(TwoPiL * pout[mu]) * coor;
|
||||
}
|
||||
Sin = Sin*exp(-Ci*pdotxin); //phase corrections
|
||||
Sout = Sout*exp(-Ci*pdotxout);
|
||||
|
||||
////Set up gamma vector//////////////////////////
|
||||
std::vector<Gamma> gammavector;
|
||||
for( int i=0; i<Gamma::nGamma; i++){
|
||||
Gamma::Algebra gam = i;
|
||||
gammavector.push_back(Gamma(gam));
|
||||
}
|
||||
result.bilinear.resize(Gamma::nGamma);
|
||||
/////////////////////////////////////////////////
|
||||
//LatticeSpinMatrix temp = g5*Sout;
|
||||
////////Form Vertex//////////////////////////////
|
||||
for (int i=0; i < Gamma::nGamma; i++){
|
||||
bilinear_x = g5*adj(Sout)*g5*gammavector[i]*Sin;
|
||||
result.bilinear[i] = sum(bilinear_x); //sum over lattice sites
|
||||
}
|
||||
//////////////////////////////////////////////////
|
||||
write(writer, par().output, result.bilinear);
|
||||
LOG(Message) << "Complete. Writing results to " << par().output << std:: endl;
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_Bilinear_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNPR/FourQuark.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 */
|
||||
#include <Hadrons/Modules/MNPR/FourQuark.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MNPR;
|
||||
|
||||
template class Grid::Hadrons::MNPR::TFourQuark<FIMPL,FIMPL>;
|
||||
|
@ -1,274 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNPR/FourQuark.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Julia Kettle J.R.Kettle-2@sms.ed.ac.uk
|
||||
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 Hadrons_FourQuark_hpp_
|
||||
#define Hadrons_FourQuark_hpp_
|
||||
|
||||
#include <typeinfo>
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Grid/serialisation/Serialisation.h>
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* TFourQuark *
|
||||
Performs fourquark contractions of the type tr[g5*adj(Sout)*g5*G*Sin]
|
||||
Suitable for non exceptional momenta
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MNPR)
|
||||
|
||||
class FourQuarkPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(FourQuarkPar,
|
||||
std::string, Sin, //need to make this a propogator type?
|
||||
std::string, Sout, //same
|
||||
std::string, pin,
|
||||
std::string, pout,
|
||||
bool, fullbasis,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
class TFourQuark: public Module<FourQuarkPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl1, 1);
|
||||
FERM_TYPE_ALIASES(FImpl2, 2);
|
||||
class Result: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||
std::vector<SpinColourSpinColourMatrix>, fourquark);
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
TFourQuark(const std::string name);
|
||||
// destructor
|
||||
virtual ~TFourQuark(void) {};
|
||||
// dependencies/products
|
||||
virtual std::vector<std::string> getInput(void);
|
||||
virtual std::vector<std::string> getOutput(void);
|
||||
// setup
|
||||
virtual void tensorprod(LatticeSpinColourSpinColourMatrix &lret, LatticeSpinColourMatrix a, LatticeSpinColourMatrix b);
|
||||
virtual void setup(void);
|
||||
// execution
|
||||
virtual void execute(void);
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(FourQuark, ARG(TFourQuark<FIMPL, FIMPL>), MNPR);
|
||||
|
||||
/******************************************************************************
|
||||
* TFourQuark implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
TFourQuark<FImpl1, FImpl2>::TFourQuark(const std::string name)
|
||||
: Module<FourQuarkPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
std::vector<std::string> TFourQuark<FImpl1, FImpl2>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> input = {par().Sin, par().Sout};
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
std::vector<std::string> TFourQuark<FImpl1, FImpl2>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> output = {getName()};
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
void TFourQuark<FImpl1, FImpl2>::tensorprod(LatticeSpinColourSpinColourMatrix &lret, LatticeSpinColourMatrix a, LatticeSpinColourMatrix b)
|
||||
{
|
||||
#if 0
|
||||
parallel_for(auto site=lret.begin();site<lret.end();site++) {
|
||||
for (int si; si < 4; ++si){
|
||||
for(int sj; sj <4; ++sj){
|
||||
for (int ci; ci < 3; ++ci){
|
||||
for (int cj; cj < 3; ++cj){
|
||||
for (int sk; sk < 4; ++sk){
|
||||
for(int sl; sl <4; ++sl){
|
||||
for (int ck; ck < 3; ++ck){
|
||||
for (int cl; cl < 3; ++cl){
|
||||
lret[site]()(si,sj)(ci,cj)(sk,sl)(ck,cl)=a[site]()(si,sj)(ci,cj)*b[site]()(sk,sl)(ck,cl);
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
}
|
||||
#else
|
||||
// FIXME ; is there a general need for this construct ? In which case we should encapsulate the
|
||||
// below loops in a helper function.
|
||||
//LOG(Message) << "sp co mat a is - " << a << std::endl;
|
||||
//LOG(Message) << "sp co mat b is - " << b << std::endl;
|
||||
parallel_for(auto site=lret.begin();site<lret.end();site++) {
|
||||
vTComplex left;
|
||||
for(int si=0; si < Ns; ++si){
|
||||
for(int sj=0; sj < Ns; ++sj){
|
||||
for (int ci=0; ci < Nc; ++ci){
|
||||
for (int cj=0; cj < Nc; ++cj){
|
||||
//LOG(Message) << "si, sj, ci, cj - " << si << ", " << sj << ", "<< ci << ", "<< cj << std::endl;
|
||||
left()()() = a[site]()(si,sj)(ci,cj);
|
||||
//LOG(Message) << left << std::endl;
|
||||
lret[site]()(si,sj)(ci,cj)=left()*b[site]();
|
||||
}}
|
||||
}}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
void TFourQuark<FImpl1, FImpl2>::setup(void)
|
||||
{
|
||||
envCreateLat(LatticeSpinColourMatrix, getName());
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl1, typename FImpl2>
|
||||
void TFourQuark<FImpl1, FImpl2>::execute(void)
|
||||
{
|
||||
|
||||
/*********************************************************************************
|
||||
|
||||
TFourQuark : Creates the four quark vertex required for the NPR of four-quark ops
|
||||
|
||||
V_{Gamma_1,Gamma_2} = sum_x [ ( g5 * adj(S'(x,p2)) * g5 * G1 * S'(x,p1) )_ci,cj;si,sj x ( g5 * adj(S'(x,p2)) * g5 * G2 S'(x,p1) )_ck,cl;sk,cl ]
|
||||
|
||||
Create a bilinear vertex for G1 and G2 the spin and colour indices are kept free. Where there are 16 potential Gs.
|
||||
We then find the outer product of V1 and V2, keeping the spin and colour indices uncontracted
|
||||
Then this is summed over the lattice coordinate
|
||||
Result is a SpinColourSpinColourMatrix - with 4 colour and 4 spin indices.
|
||||
We have up to 256 of these including the offdiag (G1 != G2).
|
||||
|
||||
\ /
|
||||
\p1 p1/
|
||||
\ /
|
||||
\ /
|
||||
G1 * * G2
|
||||
/ \
|
||||
/ \
|
||||
/p2 p2\
|
||||
/ \
|
||||
|
||||
*********************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
LOG(Message) << "Computing fourquark contractions '" << getName() << "' using"
|
||||
<< " momentum '" << par().Sin << "' and '" << par().Sout << "'"
|
||||
<< std::endl;
|
||||
|
||||
BinaryWriter writer(par().output);
|
||||
|
||||
PropagatorField1 &Sin = *env().template getObject<PropagatorField1>(par().Sin);
|
||||
PropagatorField2 &Sout = *env().template getObject<PropagatorField2>(par().Sout);
|
||||
std::vector<Real> pin = strToVec<Real>(par().pin), pout = strToVec<Real>(par().pout);
|
||||
bool fullbasis = par().fullbasis;
|
||||
Gamma g5(Gamma::Algebra::Gamma5);
|
||||
Result result;
|
||||
std::vector<Real> latt_size(pin.begin(), pin.end());
|
||||
LatticeComplex pdotxin(env().getGrid()), pdotxout(env().getGrid()), coor(env().getGrid());
|
||||
LatticeSpinColourMatrix bilinear_mu(env().getGrid()), bilinear_nu(env().getGrid());
|
||||
LatticeSpinColourSpinColourMatrix lret(env().getGrid());
|
||||
Complex Ci(0.0,1.0);
|
||||
|
||||
//Phase propagators
|
||||
//Sin = Grid::QCD::PropUtils::PhaseProps(Sin,pin);
|
||||
//Sout = Grid::QCD::PropUtils::PhaseProps(Sout,pout);
|
||||
|
||||
//find p.x for in and out so phase can be accounted for in propagators
|
||||
pdotxin=zero;
|
||||
pdotxout=zero;
|
||||
for (unsigned int mu = 0; mu < 4; ++mu)
|
||||
{
|
||||
Real TwoPiL = M_PI * 2.0/ latt_size[mu];
|
||||
LatticeCoordinate(coor,mu);
|
||||
pdotxin = pdotxin +(TwoPiL * pin[mu]) * coor;
|
||||
pdotxout= pdotxout +(TwoPiL * pout[mu]) * coor;
|
||||
}
|
||||
Sin = Sin*exp(-Ci*pdotxin); //phase corrections
|
||||
Sout = Sout*exp(-Ci*pdotxout);
|
||||
|
||||
|
||||
//Set up Gammas
|
||||
std::vector<Gamma> gammavector;
|
||||
for( int i=1; i<Gamma::nGamma; i+=2){
|
||||
Gamma::Algebra gam = i;
|
||||
gammavector.push_back(Gamma(gam));
|
||||
}
|
||||
|
||||
lret = zero;
|
||||
if (fullbasis == true){ // all combinations of mu and nu
|
||||
result.fourquark.resize(Gamma::nGamma/2*Gamma::nGamma/2);
|
||||
for( int mu=0; mu<Gamma::nGamma/2; mu++){
|
||||
bilinear_mu = g5*adj(Sout)*g5*gammavector[mu]*Sin;
|
||||
for ( int nu=0; nu<Gamma::nGamma; nu++){
|
||||
LatticeSpinColourMatrix bilinear_nu(env().getGrid());
|
||||
bilinear_nu = g5*adj(Sout)*g5*gammavector[nu]*Sin;
|
||||
LOG(Message) << "bilinear_nu for nu = " << nu << " is - " << bilinear_mu << std::endl;
|
||||
result.fourquark[mu*Gamma::nGamma/2 + nu] = zero;
|
||||
tensorprod(lret,bilinear_mu,bilinear_nu);
|
||||
result.fourquark[mu*Gamma::nGamma/2 + nu] = sum(lret);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.fourquark.resize(Gamma::nGamma/2);
|
||||
for ( int mu=0; mu<1; mu++){
|
||||
//for( int mu=0; mu<Gamma::nGamma/2; mu++ ){
|
||||
bilinear_mu = g5*adj(Sout)*g5*gammavector[mu]*Sin;
|
||||
//LOG(Message) << "bilinear_mu for mu = " << mu << " is - " << bilinear_mu << std::endl;
|
||||
result.fourquark[mu] = zero;
|
||||
tensorprod(lret,bilinear_mu,bilinear_mu); //tensor outer product
|
||||
result.fourquark[mu] = sum(lret);
|
||||
}
|
||||
}
|
||||
write(writer, "fourquark", result.fourquark);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_FourQuark_hpp_
|
@ -1,37 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNoise/FullVolumeSpinColorDiagonal.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
Author: Vera Guelpers <vmg1n14@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 <Hadrons/Modules/MNoise/FullVolumeSpinColorDiagonal.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MNoise;
|
||||
|
||||
template class Grid::Hadrons::MNoise::TFullVolumeSpinColorDiagonal<FIMPL>;
|
||||
template class Grid::Hadrons::MNoise::TFullVolumeSpinColorDiagonal<ZFIMPL>;
|
@ -1,122 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNoise/FullVolumeSpinColorDiagonal.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
Author: Vera Guelpers <vmg1n14@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 */
|
||||
#ifndef Hadrons_MNoise_FullVolumeSpinColorDiagonal_hpp_
|
||||
#define Hadrons_MNoise_FullVolumeSpinColorDiagonal_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/DilutedNoise.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Generate full volume spin-color diagonal noise *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MNoise)
|
||||
|
||||
class FullVolumeSpinColorDiagonalPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(FullVolumeSpinColorDiagonalPar,
|
||||
unsigned int, nsrc);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TFullVolumeSpinColorDiagonal: public Module<FullVolumeSpinColorDiagonalPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
// constructor
|
||||
TFullVolumeSpinColorDiagonal(const std::string name);
|
||||
// destructor
|
||||
virtual ~TFullVolumeSpinColorDiagonal(void) {};
|
||||
// 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_TMP(FullVolumeSpinColorDiagonal, TFullVolumeSpinColorDiagonal<FIMPL>, MNoise);
|
||||
MODULE_REGISTER_TMP(ZFullVolumeSpinColorDiagonal, TFullVolumeSpinColorDiagonal<ZFIMPL>, MNoise);
|
||||
|
||||
/******************************************************************************
|
||||
* TFullVolumeSpinColorDiagonal implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TFullVolumeSpinColorDiagonal<FImpl>::TFullVolumeSpinColorDiagonal(const std::string name)
|
||||
: Module<FullVolumeSpinColorDiagonalPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TFullVolumeSpinColorDiagonal<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TFullVolumeSpinColorDiagonal<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TFullVolumeSpinColorDiagonal<FImpl>::setup(void)
|
||||
{
|
||||
envCreateDerived(DilutedNoise<FImpl>,
|
||||
FullVolumeSpinColorDiagonalNoise<FImpl>,
|
||||
getName(), 1, envGetGrid(FermionField), par().nsrc);
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TFullVolumeSpinColorDiagonal<FImpl>::execute(void)
|
||||
{
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, getName());
|
||||
LOG(Message) << "Generating full volume, spin-color diagonal noise" << std::endl;
|
||||
noise.generateNoise(rng4d());
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MNoise_FullVolumeSpinColorDiagonal_hpp_
|
@ -1,35 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNoise/TimeDilutedSpinColorDiagonal.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MNoise/TimeDilutedSpinColorDiagonal.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MNoise;
|
||||
|
||||
template class Grid::Hadrons::MNoise::TTimeDilutedSpinColorDiagonal<FIMPL>;
|
||||
template class Grid::Hadrons::MNoise::TTimeDilutedSpinColorDiagonal<ZFIMPL>;
|
@ -1,114 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MNoise/TimeDilutedSpinColorDiagonal.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_MNoise_TimeDilutedSpinColorDiagonal_hpp_
|
||||
#define Hadrons_MNoise_TimeDilutedSpinColorDiagonal_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/DilutedNoise.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Generate time diluted spin-color diagonal noise *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MNoise)
|
||||
|
||||
template <typename FImpl>
|
||||
class TTimeDilutedSpinColorDiagonal: public Module<NoPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
// constructor
|
||||
TTimeDilutedSpinColorDiagonal(const std::string name);
|
||||
// destructor
|
||||
virtual ~TTimeDilutedSpinColorDiagonal(void) {};
|
||||
// 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_TMP(TimeDilutedSpinColorDiagonal, TTimeDilutedSpinColorDiagonal<FIMPL>, MNoise);
|
||||
MODULE_REGISTER_TMP(ZTimeDilutedSpinColorDiagonal, TTimeDilutedSpinColorDiagonal<ZFIMPL>, MNoise);
|
||||
|
||||
/******************************************************************************
|
||||
* TTimeDilutedSpinColorDiagonal implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TTimeDilutedSpinColorDiagonal<FImpl>::TTimeDilutedSpinColorDiagonal(const std::string name)
|
||||
: Module<NoPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TTimeDilutedSpinColorDiagonal<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TTimeDilutedSpinColorDiagonal<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TTimeDilutedSpinColorDiagonal<FImpl>::setup(void)
|
||||
{
|
||||
envCreateDerived(DilutedNoise<FImpl>,
|
||||
TimeDilutedSpinColorDiagonalNoise<FImpl>,
|
||||
getName(), 1, envGetGrid(FermionField));
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TTimeDilutedSpinColorDiagonal<FImpl>::execute(void)
|
||||
{
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, getName());
|
||||
|
||||
LOG(Message) << "Generating time-diluted, spin-color diagonal noise" << std::endl;
|
||||
noise.generateNoise(rng4d());
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MNoise_TimeDilutedSpinColorDiagonal_hpp_
|
@ -1,38 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MScalarSUN/StochFreeField.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MScalarSUN/StochFreeField.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MScalarSUN;
|
||||
|
||||
template class Grid::Hadrons::MScalarSUN::TStochFreeField<ScalarNxNAdjImplR<2>>;
|
||||
template class Grid::Hadrons::MScalarSUN::TStochFreeField<ScalarNxNAdjImplR<3>>;
|
||||
template class Grid::Hadrons::MScalarSUN::TStochFreeField<ScalarNxNAdjImplR<4>>;
|
||||
template class Grid::Hadrons::MScalarSUN::TStochFreeField<ScalarNxNAdjImplR<5>>;
|
||||
template class Grid::Hadrons::MScalarSUN::TStochFreeField<ScalarNxNAdjImplR<6>>;
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/A2AAslashVectors.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Hadrons/Modules/MSolver/A2AAslashVectors.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSolver;
|
||||
|
||||
template class Grid::Hadrons::MSolver::TA2AAslashVectors<FIMPL>;
|
||||
template class Grid::Hadrons::MSolver::TA2AAslashVectors<ZFIMPL>;
|
@ -1,195 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/A2AAslashVectors.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@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_MSolver_A2AAslashVectors_hpp_
|
||||
#define Hadrons_MSolver_A2AAslashVectors_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/Solver.hpp>
|
||||
#include <Hadrons/A2AVectors.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Create all-to-all V & W vectors *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||
|
||||
/****************************************************************************
|
||||
* Calculate a sequential propagator on an insertion of i*g_mu*A_mu
|
||||
* on an A2A vector
|
||||
*
|
||||
* vv_i(y) = S(y,x) * i * g_mu*A_mu(x) * v_i(x)
|
||||
*
|
||||
* with
|
||||
*
|
||||
* - vector: A2A vector v_i(x)
|
||||
* - emField: A_mu(x): electromagnetic photon field
|
||||
* - solver: the solver for calculating the sequential propagator
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class A2AAslashVectorsPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AAslashVectorsPar,
|
||||
std::string, vector,
|
||||
std::string, emField,
|
||||
std::string, solver,
|
||||
std::string, output,
|
||||
bool, multiFile);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TA2AAslashVectors : public Module<A2AAslashVectorsPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
SOLVER_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
typedef PhotonR::GaugeField EmField;
|
||||
public:
|
||||
// constructor
|
||||
TA2AAslashVectors(const std::string name);
|
||||
// destructor
|
||||
virtual ~TA2AAslashVectors(void) {};
|
||||
// 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:
|
||||
unsigned int Ls_;
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(A2AAslashVectors, TA2AAslashVectors<FIMPL>, MSolver);
|
||||
MODULE_REGISTER_TMP(ZA2AAslashVectors, TA2AAslashVectors<ZFIMPL>, MSolver);
|
||||
|
||||
/******************************************************************************
|
||||
* TA2AAslashVectors implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TA2AAslashVectors<FImpl>::TA2AAslashVectors(const std::string name)
|
||||
: Module<A2AAslashVectorsPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TA2AAslashVectors<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().vector, par().emField, par().solver};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TA2AAslashVectors<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TA2AAslashVectors<FImpl>::setup(void)
|
||||
{
|
||||
Ls_ = env().getObjectLs(par().solver);
|
||||
auto &vvector = envGet(std::vector<FermionField>, par().vector);
|
||||
unsigned int Nmodes = vvector.size();
|
||||
envCreate(std::vector<FermionField>, getName(), 1,
|
||||
Nmodes, envGetGrid(FermionField));
|
||||
|
||||
envTmpLat(FermionField, "v4dtmp");
|
||||
envTmpLat(FermionField, "v5dtmp", Ls_);
|
||||
envTmpLat(FermionField, "v5dtmp_sol", Ls_);
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TA2AAslashVectors<FImpl>::execute(void)
|
||||
{
|
||||
auto &solver = envGet(Solver, par().solver);
|
||||
auto &stoch_photon = envGet(EmField, par().emField);
|
||||
auto &vvector = envGet(std::vector<FermionField>, par().vector);
|
||||
auto &Aslashv = envGet(std::vector<FermionField>, getName());
|
||||
unsigned int Nmodes = vvector.size();
|
||||
auto &mat = solver.getFMat();
|
||||
envGetTmp(FermionField, v4dtmp);
|
||||
envGetTmp(FermionField, v5dtmp);
|
||||
envGetTmp(FermionField, v5dtmp_sol);
|
||||
|
||||
Complex ci(0.0,1.0);
|
||||
|
||||
startTimer("Seq Aslash");
|
||||
LOG(Message) << "Calculate Sequential propagator on Aslash * v with the A2A vector "
|
||||
<< par().vector << " and the photon field " << par().emField << std::endl;
|
||||
for(unsigned int i=0; i<Nmodes; i++)
|
||||
{
|
||||
v4dtmp = zero;
|
||||
startTimer("Multiply Aslash");
|
||||
for(unsigned int mu=0;mu<=3;mu++)
|
||||
{
|
||||
Gamma gmu(Gamma::gmu[mu]);
|
||||
v4dtmp += ci * PeekIndex<LorentzIndex>(stoch_photon, mu) * (gmu * vvector[i]);
|
||||
}
|
||||
stopTimer("Multiply Aslash");
|
||||
|
||||
startTimer("Inversion");
|
||||
if (Ls_ == 1)
|
||||
{
|
||||
solver(Aslashv[i], v4dtmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.ImportPhysicalFermionSource(v4dtmp, v5dtmp);
|
||||
solver(v5dtmp_sol, v5dtmp);
|
||||
mat.ExportPhysicalFermionSolution(v5dtmp_sol, v4dtmp);
|
||||
Aslashv[i] = v4dtmp;
|
||||
}
|
||||
stopTimer("Inversion");
|
||||
}
|
||||
stopTimer("Seq Aslash");
|
||||
if (!par().output.empty())
|
||||
{
|
||||
startTimer("I/O");
|
||||
A2AVectorsIo::write(par().output, Aslashv, par().multiFile, vm().getTrajectory());
|
||||
stopTimer("I/O");
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MSolver_A2AAslashVectors_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/A2AVectors.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: fionnoh <fionnoh@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 <Hadrons/Modules/MSolver/A2AVectors.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSolver;
|
||||
|
||||
template class Grid::Hadrons::MSolver::TA2AVectors<FIMPL, BaseFermionEigenPack<FIMPL>>;
|
||||
template class Grid::Hadrons::MSolver::TA2AVectors<ZFIMPL, BaseFermionEigenPack<ZFIMPL>>;
|
@ -1,258 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/A2AVectors.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: fionnoh <fionnoh@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_MSolver_A2AVectors_hpp_
|
||||
#define Hadrons_MSolver_A2AVectors_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/Solver.hpp>
|
||||
#include <Hadrons/EigenPack.hpp>
|
||||
#include <Hadrons/A2AVectors.hpp>
|
||||
#include <Hadrons/DilutedNoise.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Create all-to-all V & W vectors *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||
|
||||
class A2AVectorsPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AVectorsPar,
|
||||
std::string, noise,
|
||||
std::string, action,
|
||||
std::string, eigenPack,
|
||||
std::string, solver,
|
||||
std::string, output,
|
||||
bool, multiFile);
|
||||
};
|
||||
|
||||
template <typename FImpl, typename Pack>
|
||||
class TA2AVectors : public Module<A2AVectorsPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
SOLVER_TYPE_ALIASES(FImpl,);
|
||||
typedef HADRONS_DEFAULT_SCHUR_A2A<FImpl> A2A;
|
||||
public:
|
||||
// constructor
|
||||
TA2AVectors(const std::string name);
|
||||
// destructor
|
||||
virtual ~TA2AVectors(void) {};
|
||||
// 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:
|
||||
std::string solverName_;
|
||||
unsigned int Nl_{0};
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(A2AVectors,
|
||||
ARG(TA2AVectors<FIMPL, BaseFermionEigenPack<FIMPL>>), MSolver);
|
||||
MODULE_REGISTER_TMP(ZA2AVectors,
|
||||
ARG(TA2AVectors<ZFIMPL, BaseFermionEigenPack<ZFIMPL>>), MSolver);
|
||||
|
||||
/******************************************************************************
|
||||
* TA2AVectors implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename Pack>
|
||||
TA2AVectors<FImpl, Pack>::TA2AVectors(const std::string name)
|
||||
: Module<A2AVectorsPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename Pack>
|
||||
std::vector<std::string> TA2AVectors<FImpl, Pack>::getInput(void)
|
||||
{
|
||||
std::string sub_string;
|
||||
std::vector<std::string> in;
|
||||
|
||||
if (!par().eigenPack.empty())
|
||||
{
|
||||
in.push_back(par().eigenPack);
|
||||
sub_string = (!par().eigenPack.empty()) ? "_subtract" : "";
|
||||
}
|
||||
in.push_back(par().solver + sub_string);
|
||||
in.push_back(par().noise);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl, typename Pack>
|
||||
std::vector<std::string> TA2AVectors<FImpl, Pack>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName() + "_v", getName() + "_w"};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename Pack>
|
||||
void TA2AVectors<FImpl, Pack>::setup(void)
|
||||
{
|
||||
bool hasLowModes = (!par().eigenPack.empty());
|
||||
std::string sub_string = (hasLowModes) ? "_subtract" : "";
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, par().noise);
|
||||
auto &action = envGet(FMat, par().action);
|
||||
auto &solver = envGet(Solver, par().solver + sub_string);
|
||||
int Ls = env().getObjectLs(par().action);
|
||||
|
||||
if (hasLowModes)
|
||||
{
|
||||
auto &epack = envGet(Pack, par().eigenPack);
|
||||
Nl_ = epack.evec.size();
|
||||
}
|
||||
envCreate(std::vector<FermionField>, getName() + "_v", 1,
|
||||
Nl_ + noise.size(), envGetGrid(FermionField));
|
||||
envCreate(std::vector<FermionField>, getName() + "_w", 1,
|
||||
Nl_ + noise.size(), envGetGrid(FermionField));
|
||||
if (Ls > 1)
|
||||
{
|
||||
envTmpLat(FermionField, "f5", Ls);
|
||||
}
|
||||
envTmp(A2A, "a2a", 1, action, solver);
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename Pack>
|
||||
void TA2AVectors<FImpl, Pack>::execute(void)
|
||||
{
|
||||
std::string sub_string = (Nl_ > 0) ? "_subtract" : "";
|
||||
auto &action = envGet(FMat, par().action);
|
||||
auto &solver = envGet(Solver, par().solver + sub_string);
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, par().noise);
|
||||
auto &v = envGet(std::vector<FermionField>, getName() + "_v");
|
||||
auto &w = envGet(std::vector<FermionField>, getName() + "_w");
|
||||
int Ls = env().getObjectLs(par().action);
|
||||
|
||||
envGetTmp(A2A, a2a);
|
||||
|
||||
if (Nl_ > 0)
|
||||
{
|
||||
LOG(Message) << "Computing all-to-all vectors "
|
||||
<< " using eigenpack '" << par().eigenPack << "' ("
|
||||
<< Nl_ << " low modes) and noise '"
|
||||
<< par().noise << "' (" << noise.size()
|
||||
<< " noise vectors)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Message) << "Computing all-to-all vectors "
|
||||
<< " using noise '" << par().noise << "' (" << noise.size()
|
||||
<< " noise vectors)" << std::endl;
|
||||
}
|
||||
// Low modes
|
||||
for (unsigned int il = 0; il < Nl_; il++)
|
||||
{
|
||||
auto &epack = envGet(Pack, par().eigenPack);
|
||||
|
||||
startTimer("V low mode");
|
||||
LOG(Message) << "V vector i = " << il << " (low mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeLowModeV(v[il], epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeLowModeV5D(v[il], f5, epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
stopTimer("V low mode");
|
||||
startTimer("W low mode");
|
||||
LOG(Message) << "W vector i = " << il << " (low mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeLowModeW(w[il], epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeLowModeW5D(w[il], f5, epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
stopTimer("W low mode");
|
||||
}
|
||||
|
||||
// High modes
|
||||
for (unsigned int ih = 0; ih < noise.size(); ih++)
|
||||
{
|
||||
startTimer("V high mode");
|
||||
LOG(Message) << "V vector i = " << Nl_ + ih
|
||||
<< " (" << ((Nl_ > 0) ? "high " : "")
|
||||
<< "stochastic mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeHighModeV(v[Nl_ + ih], noise[ih]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeHighModeV5D(v[Nl_ + ih], f5, noise[ih]);
|
||||
}
|
||||
stopTimer("V high mode");
|
||||
startTimer("W high mode");
|
||||
LOG(Message) << "W vector i = " << Nl_ + ih
|
||||
<< " (" << ((Nl_ > 0) ? "high " : "")
|
||||
<< "stochastic mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeHighModeW(w[Nl_ + ih], noise[ih]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeHighModeW5D(w[Nl_ + ih], f5, noise[ih]);
|
||||
}
|
||||
stopTimer("W high mode");
|
||||
}
|
||||
|
||||
// I/O if necessary
|
||||
if (!par().output.empty())
|
||||
{
|
||||
startTimer("V I/O");
|
||||
A2AVectorsIo::write(par().output + "_v", v, par().multiFile, vm().getTrajectory());
|
||||
stopTimer("V I/O");
|
||||
startTimer("W I/O");
|
||||
A2AVectorsIo::write(par().output + "_w", w, par().multiFile, vm().getTrajectory());
|
||||
stopTimer("W I/O");
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MSolver_A2AVectors_hpp_
|
@ -1,85 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/Guesser.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_MSolver_Guesser_hpp_
|
||||
#define Hadrons_MSolver_Guesser_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/EigenPack.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||
|
||||
template <typename FImpl, int nBasis>
|
||||
std::shared_ptr<LinearFunction<typename FImpl::FermionField>>
|
||||
makeGuesser(const std::string epackName)
|
||||
{
|
||||
typedef typename FImpl::FermionField FermionField;
|
||||
typedef BaseFermionEigenPack<FImpl> EPack;
|
||||
typedef CoarseFermionEigenPack<FImpl, nBasis> CoarseEPack;
|
||||
typedef DeflatedGuesser<FermionField> FineGuesser;
|
||||
typedef LocalCoherenceDeflatedGuesser<
|
||||
FermionField, typename CoarseEPack::CoarseField> CoarseGuesser;
|
||||
|
||||
std::shared_ptr<LinearFunction<typename FImpl::FermionField>> guesserPt;
|
||||
|
||||
DEFINE_ENV_LAMBDA;
|
||||
|
||||
if (epackName.empty())
|
||||
{
|
||||
guesserPt.reset(new ZeroGuesser<FermionField>());
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
auto &epack = envGetDerived(EPack, CoarseEPack, epackName);
|
||||
|
||||
LOG(Message) << "using low-mode deflation with coarse eigenpack '"
|
||||
<< epackName << "' ("
|
||||
<< epack.evecCoarse.size() << " modes)" << std::endl;
|
||||
guesserPt.reset(new CoarseGuesser(epack.evec, epack.evecCoarse,
|
||||
epack.evalCoarse));
|
||||
}
|
||||
catch (Exceptions::ObjectType &e)
|
||||
{
|
||||
auto &epack = envGet(EPack, epackName);
|
||||
|
||||
LOG(Message) << "using low-mode deflation with eigenpack '"
|
||||
<< epackName << "' ("
|
||||
<< epack.evec.size() << " modes)" << std::endl;
|
||||
guesserPt.reset(new FineGuesser(epack.evec, epack.eval));
|
||||
}
|
||||
}
|
||||
|
||||
return guesserPt;
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,35 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSolver;
|
||||
|
||||
template class Grid::Hadrons::MSolver::TMixedPrecisionRBPrecCG<FIMPLF, FIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>;
|
||||
template class Grid::Hadrons::MSolver::TMixedPrecisionRBPrecCG<ZFIMPLF, ZFIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>;
|
@ -1,197 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_MSolver_MixedPrecisionRBPrecCG_hpp_
|
||||
#define Hadrons_MSolver_MixedPrecisionRBPrecCG_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/Solver.hpp>
|
||||
#include <Hadrons/EigenPack.hpp>
|
||||
#include <Hadrons/Modules/MSolver/Guesser.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Mixed precision schur red-black preconditioned CG *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||
|
||||
class MixedPrecisionRBPrecCGPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(MixedPrecisionRBPrecCGPar,
|
||||
std::string , innerAction,
|
||||
std::string , outerAction,
|
||||
unsigned int, maxInnerIteration,
|
||||
unsigned int, maxOuterIteration,
|
||||
double , residual,
|
||||
std::string , eigenPack);
|
||||
};
|
||||
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
class TMixedPrecisionRBPrecCG: public Module<MixedPrecisionRBPrecCGPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImplInner, Inner);
|
||||
FERM_TYPE_ALIASES(FImplOuter, Outer);
|
||||
SOLVER_TYPE_ALIASES(FImplOuter,);
|
||||
typedef HADRONS_DEFAULT_SCHUR_OP<FMatInner, FermionFieldInner> SchurFMatInner;
|
||||
typedef HADRONS_DEFAULT_SCHUR_OP<FMatOuter, FermionFieldOuter> SchurFMatOuter;
|
||||
private:
|
||||
template <typename Field>
|
||||
class OperatorFunctionWrapper: public OperatorFunction<Field>
|
||||
{
|
||||
public:
|
||||
OperatorFunctionWrapper(LinearFunction<Field> &fn): fn_(fn) {};
|
||||
virtual ~OperatorFunctionWrapper(void) = default;
|
||||
virtual void operator()(LinearOperatorBase<Field> &op,
|
||||
const Field &in, Field &out)
|
||||
{
|
||||
fn_(in, out);
|
||||
}
|
||||
private:
|
||||
LinearFunction<Field> &fn_;
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
TMixedPrecisionRBPrecCG(const std::string name);
|
||||
// destructor
|
||||
virtual ~TMixedPrecisionRBPrecCG(void) {};
|
||||
// dependency relation
|
||||
virtual std::vector<std::string> getInput(void);
|
||||
virtual std::vector<std::string> getReference(void);
|
||||
virtual std::vector<std::string> getOutput(void);
|
||||
// setup
|
||||
virtual void setup(void);
|
||||
// execution
|
||||
virtual void execute(void);
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(MixedPrecisionRBPrecCG,
|
||||
ARG(TMixedPrecisionRBPrecCG<FIMPLF, FIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>), MSolver);
|
||||
MODULE_REGISTER_TMP(ZMixedPrecisionRBPrecCG,
|
||||
ARG(TMixedPrecisionRBPrecCG<ZFIMPLF, ZFIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>), MSolver);
|
||||
|
||||
/******************************************************************************
|
||||
* TMixedPrecisionRBPrecCG implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||
::TMixedPrecisionRBPrecCG(const std::string name)
|
||||
: Module<MixedPrecisionRBPrecCGPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
std::vector<std::string> TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||
::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
std::vector<std::string> TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||
::getReference(void)
|
||||
{
|
||||
std::vector<std::string> ref = {par().innerAction, par().outerAction};
|
||||
|
||||
if (!par().eigenPack.empty())
|
||||
{
|
||||
ref.push_back(par().eigenPack);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
std::vector<std::string> TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||
::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName(), getName() + "_subtract"};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
void TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||
::setup(void)
|
||||
{
|
||||
LOG(Message) << "Setting up Schur red-black preconditioned mixed-precision "
|
||||
<< "CG for inner/outer action '" << par().innerAction
|
||||
<< "'/'" << par().outerAction << "', residual "
|
||||
<< par().residual << ", and maximum inner/outer iteration "
|
||||
<< par().maxInnerIteration << "/" << par().maxOuterIteration
|
||||
<< std::endl;
|
||||
|
||||
auto Ls = env().getObjectLs(par().innerAction);
|
||||
auto &imat = envGet(FMatInner, par().innerAction);
|
||||
auto &omat = envGet(FMatOuter, par().outerAction);
|
||||
auto guesserPt = makeGuesser<FImplOuter, nBasis>(par().eigenPack);
|
||||
|
||||
auto makeSolver = [&imat, &omat, guesserPt, Ls, this](bool subGuess)
|
||||
{
|
||||
return [&imat, &omat, guesserPt, subGuess, Ls, this]
|
||||
(FermionFieldOuter &sol, const FermionFieldOuter &source)
|
||||
{
|
||||
typedef typename FermionFieldInner::vector_type VTypeInner;
|
||||
|
||||
SchurFMatInner simat(imat);
|
||||
SchurFMatOuter somat(omat);
|
||||
MixedPrecisionConjugateGradient<FermionFieldOuter, FermionFieldInner>
|
||||
mpcg(par().residual, par().maxInnerIteration,
|
||||
par().maxOuterIteration,
|
||||
env().template getRbGrid<VTypeInner>(Ls),
|
||||
simat, somat);
|
||||
OperatorFunctionWrapper<FermionFieldOuter> wmpcg(mpcg);
|
||||
HADRONS_DEFAULT_SCHUR_SOLVE<FermionFieldOuter> schurSolver(wmpcg);
|
||||
schurSolver.subtractGuess(subGuess);
|
||||
schurSolver(omat, source, sol, *guesserPt);
|
||||
};
|
||||
};
|
||||
auto solver = makeSolver(false);
|
||||
envCreate(Solver, getName(), Ls, solver, omat);
|
||||
auto solver_subtract = makeSolver(true);
|
||||
envCreate(Solver, getName() + "_subtract", Ls, solver_subtract, omat);
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||
void TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||
::execute(void)
|
||||
{}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MSolver_MixedPrecisionRBPrecCG_hpp_
|
@ -1,7 +0,0 @@
|
||||
#include <Hadrons/Modules/MSource/Convolution.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSource;
|
||||
|
||||
template class Grid::Hadrons::MSource::TConvolution<FIMPL>;
|
@ -1,130 +0,0 @@
|
||||
#ifndef Hadrons_MSource_Convolution_hpp_
|
||||
#define Hadrons_MSource_Convolution_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Convolution *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSource)
|
||||
|
||||
class ConvolutionPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(ConvolutionPar,
|
||||
std::string, field,
|
||||
std::string, filter,
|
||||
std::string, mom);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TConvolution: public Module<ConvolutionPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
// constructor
|
||||
TConvolution(const std::string name);
|
||||
// destructor
|
||||
virtual ~TConvolution(void) {};
|
||||
// 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:
|
||||
std::vector<int> mom_;
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(Convolution, TConvolution<FIMPL>, MSource);
|
||||
|
||||
/******************************************************************************
|
||||
* TConvolution implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TConvolution<FImpl>::TConvolution(const std::string name)
|
||||
: Module<ConvolutionPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TConvolution<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().field, par().filter};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TConvolution<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TConvolution<FImpl>::setup(void)
|
||||
{
|
||||
mom_ = strToVec<int>(par().mom);
|
||||
if(mom_.size() != env().getNd()) {
|
||||
HADRONS_ERROR(Size, std::string("momentum has ")
|
||||
+ std::to_string(mom_.size()) + " instead of "
|
||||
+ std::to_string(env().getNd()) + " components");
|
||||
}
|
||||
|
||||
envCreateLat(PropagatorField, getName());
|
||||
envTmpLat(ComplexField, "momfield");
|
||||
envTmp(FFT, "fft", 1, env().getGrid());
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TConvolution<FImpl>::execute(void)
|
||||
{
|
||||
auto &filter = envGet(ComplexField, par().filter);
|
||||
auto &field = envGet(PropagatorField, par().field);
|
||||
auto &out = envGet(PropagatorField, getName());
|
||||
envGetTmp(ComplexField, momfield);
|
||||
envGetTmp(FFT, fft);
|
||||
|
||||
std::vector<int> mask(env().getNd(), 1);
|
||||
mask.back()=0; //transform only the spatial dimensions
|
||||
|
||||
startTimer("Fourier transform");
|
||||
fft.FFT_dim_mask(momfield, filter, mask, FFT::forward);
|
||||
fft.FFT_dim_mask(out, field, mask, FFT::forward);
|
||||
stopTimer("Fourier transform");
|
||||
|
||||
startTimer("momentum-space multiplication");
|
||||
out=momfield*out;
|
||||
stopTimer("momentum-space multiplication");
|
||||
|
||||
startTimer("inserting momentum");
|
||||
for(int mu=0; mu<env().getNd(); mu++)
|
||||
{
|
||||
if(mom_[mu]!=0)
|
||||
{
|
||||
out=Cshift(out, mu, -mom_[mu]);
|
||||
}
|
||||
}
|
||||
stopTimer("inserting momentum");
|
||||
|
||||
startTimer("Fourier transform");
|
||||
fft.FFT_dim_mask(out, out, mask, FFT::backward);
|
||||
stopTimer("Fourier transform");
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MSource_Convolution_hpp_
|
@ -1,8 +0,0 @@
|
||||
#include <Hadrons/Modules/MSource/Gauss.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSource;
|
||||
|
||||
template class Grid::Hadrons::MSource::TGauss<FIMPL>;
|
||||
template class Grid::Hadrons::MSource::TGauss<ScalarImplCR>;
|
@ -1,173 +0,0 @@
|
||||
#ifndef Hadrons_MSource_Gauss_hpp_
|
||||
#define Hadrons_MSource_Gauss_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Gauss *
|
||||
* result[n] = 1/(sqrt(2*pi)*width)^dim *
|
||||
* * exp(-|n-position|^2/(2*width^2)) *
|
||||
* * exp(i*2*pi/L*mom*n) *
|
||||
* where: *
|
||||
* n=(n[0],n[1],...,n[dim-1]) (lattice coordinate) *
|
||||
* dim=Nd-1 *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSource)
|
||||
|
||||
class GaussPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(GaussPar,
|
||||
std::string, position,
|
||||
std::string, mom,
|
||||
Integer, tA,
|
||||
Integer, tB,
|
||||
double, width);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TGauss: public Module<GaussPar>
|
||||
{
|
||||
BASIC_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
// constructor
|
||||
TGauss(const std::string name);
|
||||
// destructor
|
||||
virtual ~TGauss(void) {};
|
||||
// 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:
|
||||
std::vector<int> position_;
|
||||
std::vector<int> mom_;
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(Gauss, TGauss<FIMPL>, MSource);
|
||||
MODULE_REGISTER_TMP(ScalarGauss, TGauss<ScalarImplCR>, MSource);
|
||||
|
||||
/******************************************************************************
|
||||
* TGauss implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TGauss<FImpl>::TGauss(const std::string name)
|
||||
: Module<GaussPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TGauss<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TGauss<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TGauss<FImpl>::setup(void)
|
||||
{
|
||||
auto parse_vector = [](const std::string &vec, int dim,
|
||||
const std::string &desc)
|
||||
{
|
||||
std::vector<int> res = strToVec<int>(vec);
|
||||
if(res.size() != dim) {
|
||||
HADRONS_ERROR(Size, desc + " has "
|
||||
+ std::to_string(res.size()) + " instead of "
|
||||
+ std::to_string(dim) + " components");
|
||||
}
|
||||
return res;
|
||||
};
|
||||
position_ = parse_vector(par().position, env().getNd()-1, "position");
|
||||
mom_ = parse_vector(par().mom, env().getNd(), "momentum");
|
||||
|
||||
envCreateLat(PropagatorField, getName());
|
||||
envTmpLat(ComplexField, "component");
|
||||
envTmpLat(ComplexField, "ScalarRho");
|
||||
envTmp(LatticeInteger, "compHelper", 1, envGetGrid(ComplexField));
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TGauss<FImpl>::execute(void)
|
||||
{
|
||||
auto &rho = envGet(PropagatorField, getName());
|
||||
envGetTmp(ComplexField, component);
|
||||
envGetTmp(ComplexField, ScalarRho);
|
||||
envGetTmp(LatticeInteger, compHelper);
|
||||
const int dim=env().getNd()-1;
|
||||
const Real fact=-0.5/std::pow(par().width,2);
|
||||
const Complex i(0.0, 1.0);
|
||||
const Real Pi(M_PI);
|
||||
const SitePropagator idMat=[](){ SitePropagator s; s=1.; return s; }();
|
||||
|
||||
ScalarRho=zero;
|
||||
for(int mu=0; mu<dim; mu++) {
|
||||
assert(env().getDim(mu)%2==0);
|
||||
assert(position_[mu]>=0 && position_[mu]<env().getDim(mu));
|
||||
|
||||
const int Lmu=env().getDim(mu);
|
||||
const int LmuHalf=Lmu/2;
|
||||
const int posMu=position_[mu];
|
||||
|
||||
LatticeCoordinate(component, mu);
|
||||
LatticeCoordinate(compHelper, mu);
|
||||
|
||||
//spatial dimensions of momentum phase
|
||||
ScalarRho+=(i*(mom_[mu]*2*Pi/Lmu))*component;
|
||||
|
||||
//Gauss distribution
|
||||
component-=Complex(posMu);
|
||||
if(posMu<LmuHalf)
|
||||
{
|
||||
component=where((compHelper>Integer(posMu+LmuHalf)),
|
||||
component-Complex(Lmu),
|
||||
component);
|
||||
}
|
||||
else
|
||||
{
|
||||
component=where((compHelper<=Integer(posMu-LmuHalf)),
|
||||
component+Complex(Lmu),
|
||||
component);
|
||||
}
|
||||
ScalarRho+=component*component*fact;
|
||||
}
|
||||
|
||||
//time component of momentum phase
|
||||
LatticeCoordinate(component, dim);
|
||||
ScalarRho+=(i*(mom_.at(dim)*2*Pi/env().getDim(dim)))*component;
|
||||
|
||||
//compute scalar result
|
||||
ScalarRho=exp(ScalarRho)*Complex(std::pow(sqrt(2*Pi)*par().width,-dim));
|
||||
|
||||
//select time slices
|
||||
LatticeCoordinate(compHelper, dim);
|
||||
ScalarRho=where((compHelper>=par().tA && compHelper<=par().tB),
|
||||
ScalarRho,
|
||||
0.*ScalarRho);
|
||||
|
||||
//compute output field rho
|
||||
rho=ScalarRho*idMat;
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MSource_Gauss_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSource/Momentum.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 */
|
||||
#include <Hadrons/Modules/MSource/Momentum.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSource;
|
||||
|
||||
template class Grid::Hadrons::MSource::TMomentum<FIMPL>;
|
||||
|
@ -1,149 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSource/Momentum.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
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 Hadrons_Momentum_hpp_
|
||||
#define Hadrons_Momentum_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/*
|
||||
Plane Wave source
|
||||
-----------------
|
||||
src_x = e^i2pi/L * p *position
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Plane Wave source *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSource)
|
||||
|
||||
class MomentumPar: Serializable
|
||||
{
|
||||
public:
|
||||
//What is meant by serializable in this context
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(MomentumPar,
|
||||
std::string, mom);
|
||||
};
|
||||
|
||||
|
||||
template <typename FImpl>
|
||||
class TMomentum: public Module<MomentumPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
// constructor
|
||||
TMomentum(const std::string name);
|
||||
// destructor
|
||||
virtual ~TMomentum(void) {};
|
||||
// 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_TMP(Momentum, TMomentum<FIMPL>, MSource);
|
||||
//MODULE_REGISTER_NS(Momentum, TMomentum, MSource);
|
||||
|
||||
/******************************************************************************
|
||||
* TMomentum template implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TMomentum<FImpl>::TMomentum(const std::string name)
|
||||
: Module<MomentumPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TMomentum<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TMomentum<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TMomentum<FImpl>::setup(void)
|
||||
{
|
||||
envCreateLat(PropagatorField, getName());
|
||||
}
|
||||
|
||||
|
||||
//execution//////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TMomentum<FImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Generating planewave momentum source with momentum " << par().mom << std::endl;
|
||||
//what does this env do?
|
||||
PropagatorField &src = envGet(PropagatorField, getName());
|
||||
Lattice<iScalar<vInteger>> t(env().getGrid());
|
||||
LatticeComplex C(env().getGrid()), coor(env().getGrid());
|
||||
std::vector<Real> p;
|
||||
std::vector<Real> latt_size(GridDefaultLatt().begin(), GridDefaultLatt().end());
|
||||
Complex i(0.0,1.0);
|
||||
|
||||
LOG(Message) << " " << std::endl;
|
||||
//get the momentum from parameters
|
||||
p = strToVec<Real>(par().mom);
|
||||
C = zero;
|
||||
LOG(Message) << "momentum converted from string - " << std::to_string(p[0]) <<std::to_string(p[1]) <<std::to_string(p[2]) << std::to_string(p[3]) << std::endl;
|
||||
for(int mu=0;mu<4;mu++){
|
||||
Real TwoPiL = M_PI * 2.0/ latt_size[mu];
|
||||
LatticeCoordinate(coor,mu);
|
||||
C = C +(TwoPiL * p[mu]) * coor;
|
||||
}
|
||||
C = exp(C*i);
|
||||
LOG(Message) << "exponential of pdotx taken " << std::endl;
|
||||
src = src + C;
|
||||
LOG(Message) << "source created" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_Momentum_hpp_
|
@ -1,36 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSource/SeqAslash.cc
|
||||
|
||||
Copyright (C) 2015-2018
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Hadrons/Modules/MSource/SeqAslash.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MSource;
|
||||
|
||||
template class Grid::Hadrons::MSource::TSeqAslash<FIMPL>;
|
||||
|
@ -1,186 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MSource/SeqAslash.hpp
|
||||
|
||||
Copyright (C) 2015-2018
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Lanny91 <andrew.lawson@gmail.com>
|
||||
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
|
||||
#ifndef Hadrons_MSource_SeqAslash_hpp_
|
||||
#define Hadrons_MSource_SeqAslash_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/*
|
||||
|
||||
Sequential source
|
||||
-----------------------------
|
||||
* src_x = q_x * theta(x_3 - tA) * theta(tB - x_3) * i * A_mu g_mu * exp(i x.mom)
|
||||
|
||||
* options:
|
||||
- q: input propagator (string)
|
||||
- tA: begin timeslice (integer)
|
||||
- tB: end timesilce (integer)
|
||||
- emField: input photon field (string)
|
||||
- mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0.")
|
||||
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* SeqAslash *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSource)
|
||||
|
||||
class SeqAslashPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(SeqAslashPar,
|
||||
std::string, q,
|
||||
unsigned int, tA,
|
||||
unsigned int, tB,
|
||||
std::string, emField,
|
||||
std::string, mom);
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
class TSeqAslash: public Module<SeqAslashPar>
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
typedef PhotonR::GaugeField EmField;
|
||||
public:
|
||||
// constructor
|
||||
TSeqAslash(const std::string name);
|
||||
// destructor
|
||||
virtual ~TSeqAslash(void) {};
|
||||
// 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:
|
||||
bool hasPhase_{false};
|
||||
std::string momphName_, tName_;
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(SeqAslash, TSeqAslash<FIMPL>, MSource);
|
||||
|
||||
/******************************************************************************
|
||||
* TSeqAslash implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
TSeqAslash<FImpl>::TSeqAslash(const std::string name)
|
||||
: Module<SeqAslashPar>(name)
|
||||
, momphName_ (name + "_momph")
|
||||
, tName_ (name + "_t")
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TSeqAslash<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().q,par().emField};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TSeqAslash<FImpl>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TSeqAslash<FImpl>::setup(void)
|
||||
{
|
||||
envCreateLat(PropagatorField, getName());
|
||||
envCache(Lattice<iScalar<vInteger>>, tName_, 1, envGetGrid(LatticeComplex));
|
||||
envCacheLat(LatticeComplex, momphName_);
|
||||
envTmpLat(LatticeComplex, "coor");
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TSeqAslash<FImpl>::execute(void)
|
||||
{
|
||||
if (par().tA == par().tB)
|
||||
{
|
||||
LOG(Message) << "Generating Aslash sequential source at t= " << par().tA
|
||||
<< " using the photon field " << par().emField << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Message) << "Generating Aslash sequential source for "
|
||||
<< par().tA << " <= t <= " << par().tB
|
||||
<< " using the photon field " << par().emField << std::endl;
|
||||
}
|
||||
auto &src = envGet(PropagatorField, getName()); src=zero;
|
||||
auto &q = envGet(PropagatorField, par().q);
|
||||
auto &ph = envGet(LatticeComplex, momphName_);
|
||||
auto &t = envGet(Lattice<iScalar<vInteger>>, tName_);
|
||||
|
||||
if (!hasPhase_)
|
||||
{
|
||||
Complex i(0.0,1.0);
|
||||
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().getDim(mu))*coor;
|
||||
}
|
||||
ph = exp((Real)(2*M_PI)*i*ph);
|
||||
LatticeCoordinate(t, Tp);
|
||||
hasPhase_ = true;
|
||||
}
|
||||
auto &stoch_photon = envGet(EmField, par().emField);
|
||||
Complex ci(0.0,1.0);
|
||||
for(unsigned int mu=0;mu<=3;mu++)
|
||||
{
|
||||
Gamma gmu(Gamma::gmu[mu]);
|
||||
src = src + where((t >= par().tA) and (t <= par().tB), ci * PeekIndex<LorentzIndex>(stoch_photon, mu) *ph*(gmu*q), 0.*q);
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MSource_SeqAslash_hpp_
|
@ -1,35 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MUtilities/PrecisionCast.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MUtilities/PrecisionCast.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MUtilities;
|
||||
|
||||
template class Grid::Hadrons::MUtilities::TPrecisionCast<GIMPLD::GaugeField, GIMPLF::GaugeField>;
|
||||
template class Grid::Hadrons::MUtilities::TPrecisionCast<FIMPLD::FermionField, FIMPLF::FermionField>;
|
@ -1,124 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MUtilities/PrecisionCast.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_MUtilities_PrecisionCast_hpp_
|
||||
#define Hadrons_MUtilities_PrecisionCast_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Precision cast module *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MUtilities)
|
||||
|
||||
class PrecisionCastPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(PrecisionCastPar,
|
||||
std::string, field);
|
||||
};
|
||||
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
class TPrecisionCast: public Module<PrecisionCastPar>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
TPrecisionCast(const std::string name);
|
||||
// destructor
|
||||
virtual ~TPrecisionCast(void) {};
|
||||
// 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_TMP(GaugeSinglePrecisionCast,
|
||||
ARG(TPrecisionCast<GIMPLD::GaugeField, GIMPLF::GaugeField>),
|
||||
MUtilities);
|
||||
MODULE_REGISTER_TMP(FermionSinglePrecisionCast,
|
||||
ARG(TPrecisionCast<FIMPLD::FermionField, FIMPLF::FermionField>),
|
||||
MUtilities);
|
||||
|
||||
/******************************************************************************
|
||||
* TPrecisionCast implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
TPrecisionCast<FieldIn, FieldOut>::TPrecisionCast(const std::string name)
|
||||
: Module<PrecisionCastPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
std::vector<std::string> TPrecisionCast<FieldIn, FieldOut>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().field};
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
std::vector<std::string> TPrecisionCast<FieldIn, FieldOut>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
void TPrecisionCast<FieldIn, FieldOut>::setup(void)
|
||||
{
|
||||
envCreateLat(FieldOut, getName());
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FieldIn, typename FieldOut>
|
||||
void TPrecisionCast<FieldIn, FieldOut>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Casting field '" << par().field << "'" << std::endl;
|
||||
LOG(Message) << "In type: " << typeName<FieldIn>() << std::endl;
|
||||
LOG(Message) << "Out type: " << typeName<FieldOut>() << std::endl;
|
||||
|
||||
auto &in = envGet(FieldIn, par().field);
|
||||
auto &out = envGet(FieldOut, getName());
|
||||
|
||||
precisionChange(out, in);
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MUtilities_PrecisionCast_hpp_
|
@ -1,34 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MUtilities/RandomVectors.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Modules/MUtilities/RandomVectors.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
using namespace MUtilities;
|
||||
|
||||
template class Grid::Hadrons::MUtilities::TRandomVectors<FIMPL::FermionField>;
|
@ -1,136 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Modules/MUtilities/RandomVectors.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_MUtilities_RandomVectors_hpp_
|
||||
#define Hadrons_MUtilities_RandomVectors_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Module.hpp>
|
||||
#include <Hadrons/ModuleFactory.hpp>
|
||||
#include <Hadrons/A2AVectors.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Module generating random lattices for testing purposes *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MUtilities)
|
||||
|
||||
class RandomVectorsPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(RandomVectorsPar,
|
||||
unsigned int, size,
|
||||
unsigned int, Ls,
|
||||
std::string, output,
|
||||
bool, multiFile);
|
||||
};
|
||||
|
||||
template <typename Field>
|
||||
class TRandomVectors: public Module<RandomVectorsPar>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
TRandomVectors(const std::string name);
|
||||
// destructor
|
||||
virtual ~TRandomVectors(void) {};
|
||||
// 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_TMP(RandomFermions, TRandomVectors<FIMPL::FermionField>, MUtilities);
|
||||
|
||||
/******************************************************************************
|
||||
* TRandomVectors implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
template <typename Field>
|
||||
TRandomVectors<Field>::TRandomVectors(const std::string name)
|
||||
: Module<RandomVectorsPar>(name)
|
||||
{}
|
||||
|
||||
// dependencies/products ///////////////////////////////////////////////////////
|
||||
template <typename Field>
|
||||
std::vector<std::string> TRandomVectors<Field>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename Field>
|
||||
std::vector<std::string> TRandomVectors<Field>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename Field>
|
||||
void TRandomVectors<Field>::setup(void)
|
||||
{
|
||||
if (par().Ls > 1)
|
||||
{
|
||||
envCreate(std::vector<Field>, getName(), par().Ls, par().size,
|
||||
envGetGrid(Field, par().Ls));
|
||||
}
|
||||
else
|
||||
{
|
||||
envCreate(std::vector<Field>, getName(), 1, par().size, envGetGrid(Field));
|
||||
}
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename Field>
|
||||
void TRandomVectors<Field>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Generating " << par().size << " random vectors" << std::endl;
|
||||
|
||||
auto &vec = envGet(std::vector<Field>, getName());
|
||||
|
||||
for (unsigned int i = 0; i < vec.size(); ++i)
|
||||
{
|
||||
random(rng4d(), vec[i]);
|
||||
}
|
||||
// I/O if necessary
|
||||
if (!par().output.empty())
|
||||
{
|
||||
A2AVectorsIo::write(par().output, vec, par().multiFile, vm().getTrajectory());
|
||||
}
|
||||
}
|
||||
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_MUtilities_RandomVectors_hpp_
|
@ -1,126 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/TimerArray.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/TimerArray.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace QCD;
|
||||
using namespace Hadrons;
|
||||
|
||||
void TimerArray::startTimer(const std::string &name)
|
||||
{
|
||||
if (!name.empty())
|
||||
{
|
||||
timer_[name].Start();
|
||||
}
|
||||
}
|
||||
|
||||
GridTime TimerArray::getTimer(const std::string &name)
|
||||
{
|
||||
GridTime t;
|
||||
|
||||
if (!name.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
bool running = timer_.at(name).isRunning();
|
||||
|
||||
if (running) stopTimer(name);
|
||||
t = timer_.at(name).Elapsed();
|
||||
if (running) startTimer(name);
|
||||
}
|
||||
catch (std::out_of_range &)
|
||||
{
|
||||
t = GridTime::zero();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t = GridTime::zero();
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
double TimerArray::getDTimer(const std::string &name)
|
||||
{
|
||||
return static_cast<double>(getTimer(name).count());
|
||||
}
|
||||
|
||||
void TimerArray::startCurrentTimer(const std::string &name)
|
||||
{
|
||||
if (!name.empty())
|
||||
{
|
||||
stopCurrentTimer();
|
||||
startTimer(name);
|
||||
currentTimer_ = name;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerArray::stopTimer(const std::string &name)
|
||||
{
|
||||
if (timer_.at(name).isRunning())
|
||||
{
|
||||
timer_.at(name).Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void TimerArray::stopCurrentTimer(void)
|
||||
{
|
||||
if (!currentTimer_.empty())
|
||||
{
|
||||
stopTimer(currentTimer_);
|
||||
currentTimer_ = "";
|
||||
}
|
||||
}
|
||||
|
||||
void TimerArray::stopAllTimers(void)
|
||||
{
|
||||
for (auto &t: timer_)
|
||||
{
|
||||
stopTimer(t.first);
|
||||
}
|
||||
currentTimer_ = "";
|
||||
}
|
||||
|
||||
void TimerArray::resetTimers(void)
|
||||
{
|
||||
timer_.clear();
|
||||
currentTimer_ = "";
|
||||
}
|
||||
|
||||
std::map<std::string, GridTime> TimerArray::getTimings(void)
|
||||
{
|
||||
std::map<std::string, GridTime> timing;
|
||||
|
||||
for (auto &t: timer_)
|
||||
{
|
||||
timing[t.first] = t.second.Elapsed();
|
||||
}
|
||||
|
||||
return timing;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/TimerArray.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_TimerArray_hpp_
|
||||
#define Hadrons_TimerArray_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
class TimerArray
|
||||
{
|
||||
public:
|
||||
TimerArray(void) = default;
|
||||
virtual ~TimerArray(void) = default;
|
||||
void startTimer(const std::string &name);
|
||||
GridTime getTimer(const std::string &name);
|
||||
double getDTimer(const std::string &name);
|
||||
void startCurrentTimer(const std::string &name);
|
||||
void stopTimer(const std::string &name);
|
||||
void stopCurrentTimer(void);
|
||||
void stopAllTimers(void);
|
||||
void resetTimers(void);
|
||||
std::map<std::string, GridTime> getTimings(void);
|
||||
private:
|
||||
std::string currentTimer_;
|
||||
std::map<std::string, GridStopWatch> timer_;
|
||||
};
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_TimerArray_hpp_
|
@ -1,455 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Utilities/Contractor.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Global.hpp>
|
||||
#include <Hadrons/A2AMatrix.hpp>
|
||||
#include <Hadrons/DiskVector.hpp>
|
||||
#include <Hadrons/TimerArray.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace QCD;
|
||||
using namespace Hadrons;
|
||||
|
||||
#define TIME_MOD(t) (((t) + par.global.nt) % par.global.nt)
|
||||
|
||||
namespace Contractor
|
||||
{
|
||||
class TrajRange: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(TrajRange,
|
||||
unsigned int, start,
|
||||
unsigned int, end,
|
||||
unsigned int, step);
|
||||
};
|
||||
|
||||
class GlobalPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(GlobalPar,
|
||||
TrajRange, trajCounter,
|
||||
unsigned int, nt,
|
||||
std::string, diskVectorDir,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
class A2AMatrixPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AMatrixPar,
|
||||
std::string, file,
|
||||
std::string, dataset,
|
||||
unsigned int, cacheSize,
|
||||
std::string, name);
|
||||
};
|
||||
|
||||
class ProductPar: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(ProductPar,
|
||||
std::string, terms,
|
||||
std::vector<std::string>, times,
|
||||
std::string, translations,
|
||||
bool, translationAverage);
|
||||
};
|
||||
|
||||
class CorrelatorResult: Serializable
|
||||
{
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(CorrelatorResult,
|
||||
std::vector<Contractor::A2AMatrixPar>, a2aMatrix,
|
||||
ProductPar, contraction,
|
||||
std::vector<unsigned int>, times,
|
||||
std::vector<ComplexD>, correlator);
|
||||
};
|
||||
}
|
||||
|
||||
struct ContractorPar
|
||||
{
|
||||
Contractor::GlobalPar global;
|
||||
std::vector<Contractor::A2AMatrixPar> a2aMatrix;
|
||||
std::vector<Contractor::ProductPar> product;
|
||||
};
|
||||
|
||||
void makeTimeSeq(std::vector<std::vector<unsigned int>> &timeSeq,
|
||||
const std::vector<std::set<unsigned int>> ×,
|
||||
std::vector<unsigned int> ¤t,
|
||||
const unsigned int depth)
|
||||
{
|
||||
if (depth > 0)
|
||||
{
|
||||
for (auto t: times[times.size() - depth])
|
||||
{
|
||||
current[times.size() - depth] = t;
|
||||
makeTimeSeq(timeSeq, times, current, depth - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timeSeq.push_back(current);
|
||||
}
|
||||
}
|
||||
|
||||
void makeTimeSeq(std::vector<std::vector<unsigned int>> &timeSeq,
|
||||
const std::vector<std::set<unsigned int>> ×)
|
||||
{
|
||||
std::vector<unsigned int> current(times.size());
|
||||
|
||||
makeTimeSeq(timeSeq, times, current, times.size());
|
||||
}
|
||||
|
||||
void saveCorrelator(const Contractor::CorrelatorResult &result, const std::string dir,
|
||||
const unsigned int dt, const unsigned int traj)
|
||||
{
|
||||
std::string fileStem = "", filename;
|
||||
std::vector<std::string> terms = strToVec<std::string>(result.contraction.terms);
|
||||
|
||||
for (unsigned int i = 0; i < terms.size() - 1; i++)
|
||||
{
|
||||
fileStem += terms[i] + "_" + std::to_string(result.times[i]) + "_";
|
||||
}
|
||||
fileStem += terms.back();
|
||||
if (!result.contraction.translationAverage)
|
||||
{
|
||||
fileStem += "_dt_" + std::to_string(dt);
|
||||
}
|
||||
filename = dir + "/" + RESULT_FILE_NAME(fileStem, traj);
|
||||
std::cout << "Saving correlator to '" << filename << "'" << std::endl;
|
||||
makeFileDir(dir);
|
||||
ResultWriter writer(filename);
|
||||
write(writer, fileStem, result);
|
||||
}
|
||||
|
||||
std::set<unsigned int> parseTimeRange(const std::string str, const unsigned int nt)
|
||||
{
|
||||
std::regex rex("([0-9]+)|(([0-9]+)\\.\\.([0-9]+))");
|
||||
std::smatch sm;
|
||||
std::vector<std::string> rstr = strToVec<std::string>(str);
|
||||
std::set<unsigned int> tSet;
|
||||
|
||||
for (auto &s: rstr)
|
||||
{
|
||||
std::regex_match(s, sm, rex);
|
||||
if (sm[1].matched)
|
||||
{
|
||||
unsigned int t;
|
||||
|
||||
t = std::stoi(sm[1].str());
|
||||
if (t >= nt)
|
||||
{
|
||||
HADRONS_ERROR(Range, "time out of range (from expression '" + str + "')");
|
||||
}
|
||||
tSet.insert(t);
|
||||
}
|
||||
else if (sm[2].matched)
|
||||
{
|
||||
unsigned int ta, tb;
|
||||
|
||||
ta = std::stoi(sm[3].str());
|
||||
tb = std::stoi(sm[4].str());
|
||||
if ((ta >= nt) or (tb >= nt))
|
||||
{
|
||||
HADRONS_ERROR(Range, "time out of range (from expression '" + str + "')");
|
||||
}
|
||||
for (unsigned int ti = ta; ti <= tb; ++ti)
|
||||
{
|
||||
tSet.insert(ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tSet;
|
||||
}
|
||||
|
||||
struct Sec
|
||||
{
|
||||
Sec(const double usec)
|
||||
{
|
||||
seconds = usec/1.0e6;
|
||||
}
|
||||
|
||||
double seconds;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<< (std::ostream& s, const Sec &&sec)
|
||||
{
|
||||
s << std::setw(10) << sec.seconds << " sec";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
struct Flops
|
||||
{
|
||||
Flops(const double flops, const double fusec)
|
||||
{
|
||||
gFlopsPerSec = flops/fusec/1.0e3;
|
||||
}
|
||||
|
||||
double gFlopsPerSec;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<< (std::ostream& s, const Flops &&f)
|
||||
{
|
||||
s << std::setw(10) << f.gFlopsPerSec << " GFlop/s";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
struct Bytes
|
||||
{
|
||||
Bytes(const double bytes, const double busec)
|
||||
{
|
||||
gBytesPerSec = bytes/busec*1.0e6/1024/1024/1024;
|
||||
}
|
||||
|
||||
double gBytesPerSec;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<< (std::ostream& s, const Bytes &&b)
|
||||
{
|
||||
s << std::setw(10) << b.gBytesPerSec << " GB/s";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// parse command line
|
||||
std::string parFilename;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " <parameter file>";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
parFilename = argv[1];
|
||||
|
||||
// parse parameter file
|
||||
ContractorPar par;
|
||||
unsigned int nMat, nCont;
|
||||
XmlReader reader(parFilename);
|
||||
|
||||
read(reader, "global", par.global);
|
||||
read(reader, "a2aMatrix", par.a2aMatrix);
|
||||
read(reader, "product", par.product);
|
||||
nMat = par.a2aMatrix.size();
|
||||
nCont = par.product.size();
|
||||
|
||||
// create diskvectors
|
||||
std::map<std::string, EigenDiskVector<ComplexD>> a2aMat;
|
||||
unsigned int cacheSize;
|
||||
|
||||
for (auto &p: par.a2aMatrix)
|
||||
{
|
||||
std::string dirName = par.global.diskVectorDir + "/" + p.name;
|
||||
|
||||
a2aMat.emplace(p.name, EigenDiskVector<ComplexD>(dirName, par.global.nt, p.cacheSize));
|
||||
}
|
||||
|
||||
// trajectory loop
|
||||
for (unsigned int traj = par.global.trajCounter.start;
|
||||
traj < par.global.trajCounter.end; traj += par.global.trajCounter.step)
|
||||
{
|
||||
std::cout << ":::::::: Trajectory " << traj << std::endl;
|
||||
|
||||
// load data
|
||||
for (auto &p: par.a2aMatrix)
|
||||
{
|
||||
std::string filename = p.file;
|
||||
double t, size;
|
||||
|
||||
tokenReplace(filename, "traj", traj);
|
||||
std::cout << "======== Loading '" << filename << "'" << std::endl;
|
||||
|
||||
A2AMatrixIo<HADRONS_A2AM_IO_TYPE> a2aIo(filename, p.dataset, par.global.nt);
|
||||
|
||||
a2aIo.load(a2aMat.at(p.name), &t);
|
||||
std::cout << "Read " << a2aIo.getSize() << " bytes in " << t/1.0e6
|
||||
<< " sec, " << a2aIo.getSize()/t*1.0e6/1024/1024 << " MB/s" << std::endl;
|
||||
}
|
||||
|
||||
// contract
|
||||
EigenDiskVector<ComplexD>::Matrix buf;
|
||||
|
||||
for (auto &p: par.product)
|
||||
{
|
||||
std::vector<std::string> term = strToVec<std::string>(p.terms);
|
||||
std::vector<std::set<unsigned int>> times;
|
||||
std::vector<std::vector<unsigned int>> timeSeq;
|
||||
std::set<unsigned int> translations;
|
||||
std::vector<A2AMatrixTr<ComplexD>> lastTerm(par.global.nt);
|
||||
A2AMatrix<ComplexD> prod, buf, tmp;
|
||||
TimerArray tAr;
|
||||
double fusec, busec, flops, bytes, tusec;
|
||||
Contractor::CorrelatorResult result;
|
||||
|
||||
tAr.startTimer("Total");
|
||||
std::cout << "======== Contraction tr(";
|
||||
for (unsigned int g = 0; g < term.size(); ++g)
|
||||
{
|
||||
std::cout << term[g] << ((g == term.size() - 1) ? ')' : '*');
|
||||
}
|
||||
std::cout << std::endl;
|
||||
if (term.size() != p.times.size() + 1)
|
||||
{
|
||||
HADRONS_ERROR(Size, "number of terms (" + std::to_string(term.size())
|
||||
+ ") different from number of times ("
|
||||
+ std::to_string(p.times.size() + 1) + ")");
|
||||
}
|
||||
for (auto &s: p.times)
|
||||
{
|
||||
times.push_back(parseTimeRange(s, par.global.nt));
|
||||
}
|
||||
for (auto &m: par.a2aMatrix)
|
||||
{
|
||||
if (std::find(result.a2aMatrix.begin(), result.a2aMatrix.end(), m) == result.a2aMatrix.end())
|
||||
{
|
||||
result.a2aMatrix.push_back(m);
|
||||
tokenReplace(result.a2aMatrix.back().file, "traj", traj);
|
||||
}
|
||||
}
|
||||
result.contraction = p;
|
||||
result.correlator.resize(par.global.nt, 0.);
|
||||
|
||||
translations = parseTimeRange(p.translations, par.global.nt);
|
||||
makeTimeSeq(timeSeq, times);
|
||||
std::cout << timeSeq.size()*translations.size()*(term.size() - 2) << " A*B, "
|
||||
<< timeSeq.size()*translations.size()*par.global.nt << " tr(A*B)"
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "* Caching transposed last term" << std::endl;
|
||||
for (unsigned int t = 0; t < par.global.nt; ++t)
|
||||
{
|
||||
tAr.startTimer("Disk vector overhead");
|
||||
const A2AMatrix<ComplexD> &ref = a2aMat.at(term.back())[t];
|
||||
tAr.stopTimer("Disk vector overhead");
|
||||
|
||||
tAr.startTimer("Transpose caching");
|
||||
lastTerm[t].resize(ref.rows(), ref.cols());
|
||||
parallel_for (unsigned int j = 0; j < ref.cols(); ++j)
|
||||
for (unsigned int i = 0; i < ref.rows(); ++i)
|
||||
{
|
||||
lastTerm[t](i, j) = ref(i, j);
|
||||
}
|
||||
tAr.stopTimer("Transpose caching");
|
||||
}
|
||||
bytes = par.global.nt*lastTerm[0].rows()*lastTerm[0].cols()*sizeof(ComplexD);
|
||||
std::cout << Sec(tAr.getDTimer("Transpose caching")) << " "
|
||||
<< Bytes(bytes, tAr.getDTimer("Transpose caching")) << std::endl;
|
||||
for (unsigned int i = 0; i < timeSeq.size(); ++i)
|
||||
{
|
||||
unsigned int dti = 0;
|
||||
auto &t = timeSeq[i];
|
||||
|
||||
result.times = t;
|
||||
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
|
||||
{
|
||||
result.correlator[tLast] = 0.;
|
||||
}
|
||||
for (auto &dt: translations)
|
||||
{
|
||||
std::cout << "* Step " << i*translations.size() + dti + 1
|
||||
<< "/" << timeSeq.size()*translations.size()
|
||||
<< " -- positions= " << t << ", dt= " << dt << std::endl;
|
||||
if (term.size() > 2)
|
||||
{
|
||||
std::cout << std::setw(8) << "products";
|
||||
}
|
||||
flops = 0.;
|
||||
bytes = 0.;
|
||||
fusec = tAr.getDTimer("A*B algebra");
|
||||
busec = tAr.getDTimer("A*B total");
|
||||
tAr.startTimer("Linear algebra");
|
||||
tAr.startTimer("Disk vector overhead");
|
||||
prod = a2aMat.at(term[0])[TIME_MOD(t[0] + dt)];
|
||||
tAr.stopTimer("Disk vector overhead");
|
||||
for (unsigned int j = 1; j < term.size() - 1; ++j)
|
||||
{
|
||||
tAr.startTimer("Disk vector overhead");
|
||||
const A2AMatrix<ComplexD> &ref = a2aMat.at(term[j])[TIME_MOD(t[j] + dt)];
|
||||
tAr.stopTimer("Disk vector overhead");
|
||||
|
||||
tAr.startTimer("A*B total");
|
||||
tAr.startTimer("A*B algebra");
|
||||
A2AContraction::mul(tmp, prod, ref);
|
||||
tAr.stopTimer("A*B algebra");
|
||||
flops += A2AContraction::mulFlops(prod, ref);
|
||||
prod = tmp;
|
||||
tAr.stopTimer("A*B total");
|
||||
bytes += 3.*tmp.rows()*tmp.cols()*sizeof(ComplexD);
|
||||
}
|
||||
if (term.size() > 2)
|
||||
{
|
||||
std::cout << Sec(tAr.getDTimer("A*B total") - busec) << " "
|
||||
<< Flops(flops, tAr.getDTimer("A*B algebra") - fusec) << " "
|
||||
<< Bytes(bytes, tAr.getDTimer("A*B total") - busec) << std::endl;
|
||||
}
|
||||
std::cout << std::setw(8) << "traces";
|
||||
flops = 0.;
|
||||
bytes = 0.;
|
||||
fusec = tAr.getDTimer("tr(A*B)");
|
||||
busec = tAr.getDTimer("tr(A*B)");
|
||||
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
|
||||
{
|
||||
tAr.startTimer("tr(A*B)");
|
||||
A2AContraction::accTrMul(result.correlator[TIME_MOD(tLast - dt)], prod, lastTerm[tLast]);
|
||||
tAr.stopTimer("tr(A*B)");
|
||||
flops += A2AContraction::accTrMulFlops(prod, lastTerm[tLast]);
|
||||
bytes += 2.*prod.rows()*prod.cols()*sizeof(ComplexD);
|
||||
}
|
||||
tAr.stopTimer("Linear algebra");
|
||||
std::cout << Sec(tAr.getDTimer("tr(A*B)") - busec) << " "
|
||||
<< Flops(flops, tAr.getDTimer("tr(A*B)") - fusec) << " "
|
||||
<< Bytes(bytes, tAr.getDTimer("tr(A*B)") - busec) << std::endl;
|
||||
if (!p.translationAverage)
|
||||
{
|
||||
saveCorrelator(result, par.global.output, dt, traj);
|
||||
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
|
||||
{
|
||||
result.correlator[tLast] = 0.;
|
||||
}
|
||||
}
|
||||
dti++;
|
||||
}
|
||||
if (p.translationAverage)
|
||||
{
|
||||
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
|
||||
{
|
||||
result.correlator[tLast] /= translations.size();
|
||||
}
|
||||
saveCorrelator(result, par.global.output, 0, traj);
|
||||
}
|
||||
}
|
||||
tAr.stopTimer("Total");
|
||||
printTimeProfile(tAr.getTimings(), tAr.getTimer("Total"));
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Utilities/Contractor.hpp
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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_Contractor_hpp_
|
||||
#define Hadrons_Contractor_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_Contractor_hpp_
|
@ -1,461 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Utilities/ContractorBenchmark.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Global.hpp>
|
||||
#include <Hadrons/A2AMatrix.hpp>
|
||||
#ifdef USE_MKL
|
||||
#include "mkl.h"
|
||||
#include "mkl_cblas.h"
|
||||
#endif
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
|
||||
#ifdef GRID_COMMS_MPI3
|
||||
#define GET_RANK(rank, nMpi) \
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &(nMpi));\
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &(rank))
|
||||
#define BARRIER() MPI_Barrier(MPI_COMM_WORLD)
|
||||
#define INIT() MPI_Init(NULL, NULL)
|
||||
#define FINALIZE() MPI_Finalize()
|
||||
#else
|
||||
#define GET_RANK(rank, nMpi) (nMpi) = 1; (rank) = 0
|
||||
#define BARRIER()
|
||||
#define INIT()
|
||||
#define FINALIZE()
|
||||
#endif
|
||||
|
||||
template <typename Function, typename MatLeft, typename MatRight>
|
||||
inline void trBenchmark(const std::string name, const MatLeft &left,
|
||||
const MatRight &right, const ComplexD ref, Function fn)
|
||||
{
|
||||
double t, flops, bytes, n = left[0].rows()*left[0].cols();
|
||||
unsigned int nMat = left.size();
|
||||
int nMpi, rank;
|
||||
ComplexD buf;
|
||||
|
||||
t = 0.;
|
||||
GET_RANK(rank, nMpi);
|
||||
t = -usecond();
|
||||
BARRIER();
|
||||
for (unsigned int i = rank*nMat/nMpi; i < (rank+1)*nMat/nMpi; ++i)
|
||||
{
|
||||
fn(buf, left[i], right[i]);
|
||||
}
|
||||
BARRIER();
|
||||
t += usecond();
|
||||
flops = nMat*(6.*n + 2.*(n - 1.));
|
||||
bytes = nMat*(2.*n*sizeof(ComplexD));
|
||||
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << std::setw(34) << name << ": diff= "
|
||||
<< std::setw(12) << std::norm(buf-ref)
|
||||
<< std::setw(10) << t/1.0e6 << " sec "
|
||||
<< std::setw(10) << flops/t/1.0e3 << " GFlop/s "
|
||||
<< std::setw(10) << bytes/t*1.0e6/1024/1024/1024 << " GB/s "
|
||||
<< std::endl;
|
||||
}
|
||||
::sleep(1);
|
||||
}
|
||||
|
||||
template <typename Function, typename MatV, typename Mat>
|
||||
inline void mulBenchmark(const std::string name, const MatV &left,
|
||||
const MatV &right, const Mat &ref, Function fn)
|
||||
{
|
||||
double t, flops, bytes;
|
||||
double nr = left[0].rows(), nc = left[0].cols(), n = nr*nc;
|
||||
unsigned int nMat = left.size();
|
||||
int nMpi, rank;
|
||||
Mat buf(left[0].rows(), left[0].rows());
|
||||
|
||||
t = 0.;
|
||||
GET_RANK(rank, nMpi);
|
||||
t = -usecond();
|
||||
BARRIER();
|
||||
for (unsigned int i = rank*nMat/nMpi; i < (rank+1)*nMat/nMpi; ++i)
|
||||
{
|
||||
fn(buf, left[i], right[i]);
|
||||
}
|
||||
BARRIER();
|
||||
t += usecond();
|
||||
flops = nMat*(nr*nr*(6.*nc + 2.*(nc - 1.)));
|
||||
bytes = nMat*(2*nc*nr*sizeof(ComplexD));
|
||||
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << std::setw(34) << name << ": diff= "
|
||||
<< std::setw(12) << (buf-ref).squaredNorm()
|
||||
<< std::setw(10) << t/1.0e6 << " sec "
|
||||
<< std::setw(10) << flops/t/1.0e3 << " GFlop/s "
|
||||
<< std::setw(10) << bytes/t*1.0e6/1024/1024/1024 << " GB/s "
|
||||
<< std::endl;
|
||||
}
|
||||
::sleep(1);
|
||||
}
|
||||
|
||||
#ifdef USE_MKL
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline void zdotuRow(ComplexD &res, const unsigned int aRow,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
const ComplexD *aPt, *bPt;
|
||||
unsigned int aInc, bInc;
|
||||
|
||||
if (MatLeft::Options == Eigen::RowMajor)
|
||||
{
|
||||
aPt = a.data() + aRow*a.cols();
|
||||
aInc = 1;
|
||||
}
|
||||
else if (MatLeft::Options == Eigen::ColMajor)
|
||||
{
|
||||
aPt = a.data() + aRow;
|
||||
aInc = a.rows();
|
||||
}
|
||||
if (MatRight::Options == Eigen::RowMajor)
|
||||
{
|
||||
bPt = b.data() + aRow;
|
||||
bInc = b.cols();
|
||||
}
|
||||
else if (MatRight::Options == Eigen::ColMajor)
|
||||
{
|
||||
bPt = b.data() + aRow*b.rows();
|
||||
bInc = 1;
|
||||
}
|
||||
cblas_zdotu_sub(a.cols(), aPt, aInc, bPt, bInc, &res);
|
||||
}
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
static inline void zdotuCol(ComplexD &res, const unsigned int aCol,
|
||||
const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
const ComplexD *aPt, *bPt;
|
||||
unsigned int aInc, bInc;
|
||||
|
||||
if (MatLeft::Options == Eigen::RowMajor)
|
||||
{
|
||||
aPt = a.data() + aCol;
|
||||
aInc = a.cols();
|
||||
}
|
||||
else if (MatLeft::Options == Eigen::ColMajor)
|
||||
{
|
||||
aPt = a.data() + aCol*a.rows();
|
||||
aInc = 1;
|
||||
}
|
||||
if (MatRight::Options == Eigen::RowMajor)
|
||||
{
|
||||
bPt = b.data() + aCol*b.cols();
|
||||
bInc = 1;
|
||||
}
|
||||
else if (MatRight::Options == Eigen::ColMajor)
|
||||
{
|
||||
bPt = b.data() + aCol;
|
||||
bInc = b.rows();
|
||||
}
|
||||
cblas_zdotu_sub(a.rows(), aPt, aInc, bPt, bInc, &res);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename MatLeft, typename MatRight>
|
||||
void fullTrBenchmark(const unsigned int ni, const unsigned int nj, const unsigned int nMat)
|
||||
{
|
||||
std::vector<MatLeft> left;
|
||||
std::vector<MatRight> right;
|
||||
MatRight buf;
|
||||
ComplexD ref;
|
||||
int rank, nMpi;
|
||||
|
||||
left.resize(nMat, MatLeft::Random(ni, nj));
|
||||
right.resize(nMat, MatRight::Random(nj, ni));
|
||||
GET_RANK(rank, nMpi);
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << "==== tr(A*B) benchmarks" << std::endl;
|
||||
std::cout << "A matrices use ";
|
||||
if (MatLeft::Options == Eigen::RowMajor)
|
||||
{
|
||||
std::cout << "row-major ordering" << std::endl;
|
||||
}
|
||||
else if (MatLeft::Options == Eigen::ColMajor)
|
||||
{
|
||||
std::cout << "col-major ordering" << std::endl;
|
||||
}
|
||||
std::cout << "B matrices use ";
|
||||
if (MatRight::Options == Eigen::RowMajor)
|
||||
{
|
||||
std::cout << "row-major ordering" << std::endl;
|
||||
}
|
||||
else if (MatRight::Options == Eigen::ColMajor)
|
||||
{
|
||||
std::cout << "col-major ordering" << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
BARRIER();
|
||||
ref = (left.back()*right.back()).trace();
|
||||
trBenchmark("Hadrons A2AContraction::accTrMul", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = 0.;
|
||||
A2AContraction::accTrMul(res, a, b);
|
||||
});
|
||||
trBenchmark("Naive loop rows first", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
auto nr = a.rows(), nc = a.cols();
|
||||
|
||||
res = 0.;
|
||||
parallel_for (unsigned int i = 0; i < nr; ++i)
|
||||
{
|
||||
ComplexD tmp = 0.;
|
||||
|
||||
for (unsigned int j = 0; j < nc; ++j)
|
||||
{
|
||||
tmp += a(i, j)*b(j, i);
|
||||
}
|
||||
parallel_critical
|
||||
{
|
||||
res += tmp;
|
||||
}
|
||||
}
|
||||
});
|
||||
trBenchmark("Naive loop cols first", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
auto nr = a.rows(), nc = a.cols();
|
||||
|
||||
res = 0.;
|
||||
parallel_for (unsigned int j = 0; j < nc; ++j)
|
||||
{
|
||||
ComplexD tmp = 0.;
|
||||
|
||||
for (unsigned int i = 0; i < nr; ++i)
|
||||
{
|
||||
tmp += a(i, j)*b(j, i);
|
||||
}
|
||||
parallel_critical
|
||||
{
|
||||
res += tmp;
|
||||
}
|
||||
}
|
||||
});
|
||||
trBenchmark("Eigen tr(A*B)", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = (a*b).trace();
|
||||
});
|
||||
trBenchmark("Eigen row-wise dot", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = 0.;
|
||||
parallel_for (unsigned int r = 0; r < a.rows(); ++r)
|
||||
{
|
||||
ComplexD tmp;
|
||||
|
||||
tmp = a.row(r).conjugate().dot(b.col(r));
|
||||
parallel_critical
|
||||
{
|
||||
res += tmp;
|
||||
}
|
||||
}
|
||||
});
|
||||
trBenchmark("Eigen col-wise dot", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = 0.;
|
||||
parallel_for (unsigned int c = 0; c < a.cols(); ++c)
|
||||
{
|
||||
ComplexD tmp;
|
||||
|
||||
tmp = a.col(c).conjugate().dot(b.row(c));
|
||||
parallel_critical
|
||||
{
|
||||
res += tmp;
|
||||
}
|
||||
}
|
||||
});
|
||||
trBenchmark("Eigen Hadamard", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = a.cwiseProduct(b.transpose()).sum();
|
||||
});
|
||||
#ifdef USE_MKL
|
||||
trBenchmark("MKL row-wise zdotu", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = 0.;
|
||||
parallel_for (unsigned int r = 0; r < a.rows(); ++r)
|
||||
{
|
||||
ComplexD tmp;
|
||||
|
||||
zdotuRow(tmp, r, a, b);
|
||||
parallel_critical
|
||||
{
|
||||
res += tmp;
|
||||
}
|
||||
}
|
||||
});
|
||||
trBenchmark("MKL col-wise zdotu", left, right, ref,
|
||||
[](ComplexD &res, const MatLeft &a, const MatRight &b)
|
||||
{
|
||||
res = 0.;
|
||||
parallel_for (unsigned int c = 0; c < a.cols(); ++c)
|
||||
{
|
||||
ComplexD tmp;
|
||||
|
||||
zdotuCol(tmp, c, a, b);
|
||||
parallel_critical
|
||||
{
|
||||
res += tmp;
|
||||
}
|
||||
}
|
||||
});
|
||||
#endif
|
||||
BARRIER();
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Mat>
|
||||
void fullMulBenchmark(const unsigned int ni, const unsigned int nj, const unsigned int nMat)
|
||||
{
|
||||
std::vector<Mat> left, right;
|
||||
Mat ref;
|
||||
int rank, nMpi;
|
||||
|
||||
left.resize(nMat, Mat::Random(ni, nj));
|
||||
right.resize(nMat, Mat::Random(nj, ni));
|
||||
GET_RANK(rank, nMpi);
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << "==== A*B benchmarks" << std::endl;
|
||||
std::cout << "all matrices use ";
|
||||
if (Mat::Options == Eigen::RowMajor)
|
||||
{
|
||||
std::cout << "row-major ordering" << std::endl;
|
||||
}
|
||||
else if (Mat::Options == Eigen::ColMajor)
|
||||
{
|
||||
std::cout << "col-major ordering" << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
BARRIER();
|
||||
ref = left.back()*right.back();
|
||||
mulBenchmark("Hadrons A2AContraction::mul", left, right, ref,
|
||||
[](Mat &res, const Mat &a, const Mat &b)
|
||||
{
|
||||
A2AContraction::mul(res, a, b);
|
||||
});
|
||||
mulBenchmark("Eigen A*B", left, right, ref,
|
||||
[](Mat &res, const Mat &a, const Mat &b)
|
||||
{
|
||||
res = a*b;
|
||||
});
|
||||
#ifdef USE_MKL
|
||||
mulBenchmark("MKL A*B", left, right, ref,
|
||||
[](Mat &res, const Mat &a, const Mat &b)
|
||||
{
|
||||
const ComplexD one(1., 0.), zero(0., 0.);
|
||||
if (Mat::Options == Eigen::RowMajor)
|
||||
{
|
||||
cblas_zgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a.rows(), b.cols(),
|
||||
a.cols(), &one, a.data(), a.cols(), b.data(), b.cols(), &zero,
|
||||
res.data(), res.cols());
|
||||
}
|
||||
else if (Mat::Options == Eigen::ColMajor)
|
||||
{
|
||||
cblas_zgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, a.rows(), b.cols(),
|
||||
a.cols(), &one, a.data(), a.rows(), b.data(), b.rows(), &zero,
|
||||
res.data(), res.rows());
|
||||
}
|
||||
});
|
||||
#endif
|
||||
BARRIER();
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// parse command line
|
||||
Eigen::Index ni, nj, nMat;
|
||||
int nMpi, rank;
|
||||
|
||||
if (argc != 4)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " <Ni> <Nj> <#matrices>";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
ni = std::stoi(argv[1]);
|
||||
nj = std::stoi(argv[2]);
|
||||
nMat = std::stoi(argv[3]);
|
||||
|
||||
INIT();
|
||||
GET_RANK(rank, nMpi);
|
||||
if (rank == 0)
|
||||
{
|
||||
std::cout << "\n*** ALL-TO-ALL MATRIX CONTRACTION BENCHMARK ***\n" << std::endl;
|
||||
std::cout << nMat << " couples of " << ni << "x" << nj << " matrices\n" << std::endl;
|
||||
|
||||
std::cout << nMpi << " MPI processes" << std::endl;
|
||||
#ifdef GRID_OMP
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp single
|
||||
std::cout << omp_get_num_threads() << " threads\n" << std::endl;
|
||||
}
|
||||
#else
|
||||
std::cout << "Single-threaded\n" << std::endl;
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_USE_MKL_ALL
|
||||
std::cout << "Eigen uses the MKL" << std::endl;
|
||||
#endif
|
||||
std::cout << "Eigen uses " << Eigen::nbThreads() << " threads" << std::endl;
|
||||
#ifdef USE_MKL
|
||||
std::cout << "MKL uses " << mkl_get_max_threads() << " threads" << std::endl;
|
||||
#endif
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
fullTrBenchmark<A2AMatrix<ComplexD>, A2AMatrix<ComplexD>>(ni, nj, nMat);
|
||||
fullTrBenchmark<A2AMatrix<ComplexD>, A2AMatrixTr<ComplexD>>(ni, nj, nMat);
|
||||
fullTrBenchmark<A2AMatrixTr<ComplexD>, A2AMatrix<ComplexD>>(ni, nj, nMat);
|
||||
fullTrBenchmark<A2AMatrixTr<ComplexD>, A2AMatrixTr<ComplexD>>(ni, nj, nMat);
|
||||
fullMulBenchmark<A2AMatrix<ComplexD>>(ni, nj, nMat);
|
||||
fullMulBenchmark<A2AMatrixTr<ComplexD>>(ni, nj, nMat);
|
||||
FINALIZE();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Utilities/EigenPackCast.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/EigenPack.hpp>
|
||||
#include <Hadrons/Environment.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace QCD;
|
||||
using namespace Hadrons;
|
||||
|
||||
template <typename FOut, typename FIn>
|
||||
void convert(const std::string outFilename, const std::string inFilename,
|
||||
const unsigned int Ls, const bool rb, const unsigned int size,
|
||||
const bool multiFile, const bool testRead)
|
||||
{
|
||||
assert(outFilename != inFilename);
|
||||
|
||||
typedef EigenPack<FOut> EPOut;
|
||||
typedef EigenPack<FIn> EPIn;
|
||||
typedef typename FOut::vector_type VTypeOut;
|
||||
typedef typename FIn::vector_type VTypeIn;
|
||||
|
||||
std::shared_ptr<GridCartesian> gInBase, gOutBase, gIn5, gOut5;
|
||||
std::shared_ptr<GridRedBlackCartesian> rbgIn, rbgOut;
|
||||
GridBase *gIn, *gOut;
|
||||
|
||||
auto dim = GridDefaultLatt();
|
||||
unsigned int nd = dim.size();
|
||||
auto simdOut = GridDefaultSimd(nd, VTypeOut::Nsimd());
|
||||
auto simdIn = GridDefaultSimd(nd, VTypeIn::Nsimd());
|
||||
|
||||
gOutBase.reset(SpaceTimeGrid::makeFourDimGrid(dim, simdOut, GridDefaultMpi()));
|
||||
gInBase.reset(SpaceTimeGrid::makeFourDimGrid(dim, simdIn, GridDefaultMpi()));
|
||||
if (rb)
|
||||
{
|
||||
if (Ls > 1)
|
||||
{
|
||||
rbgOut.reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, gOutBase.get()));
|
||||
rbgIn.reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, gInBase.get()));
|
||||
}
|
||||
else
|
||||
{
|
||||
rbgOut.reset(SpaceTimeGrid::makeFourDimRedBlackGrid(gOutBase.get()));
|
||||
rbgIn.reset(SpaceTimeGrid::makeFourDimRedBlackGrid(gInBase.get()));
|
||||
}
|
||||
gOut = rbgOut.get();
|
||||
gIn = rbgIn.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Ls > 1)
|
||||
{
|
||||
gOut5.reset(SpaceTimeGrid::makeFiveDimGrid(Ls, gOutBase.get()));
|
||||
gIn5.reset(SpaceTimeGrid::makeFiveDimGrid(Ls, gInBase.get()));
|
||||
gOut = gOut5.get();
|
||||
gIn = gIn5.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
gOut = gOutBase.get();
|
||||
gIn = gInBase.get();
|
||||
}
|
||||
}
|
||||
|
||||
FOut bufOut(gOut);
|
||||
FIn bufIn(gIn), testIn(gIn);
|
||||
ScidacWriter binWriter(gOut->IsBoss());
|
||||
ScidacReader binReader;
|
||||
PackRecord record;
|
||||
RealD eval;
|
||||
|
||||
LOG(Message) << "==== EIGENPACK CONVERSION" << std::endl;
|
||||
LOG(Message) << "Lattice : " << gIn->GlobalDimensions() << std::endl;
|
||||
LOG(Message) << "Checkerboarded: " << (rb ? "yes" : "no") << std::endl;
|
||||
LOG(Message) << "In path : " << inFilename << std::endl;
|
||||
LOG(Message) << "In type : " << typeName<FIn>() << std::endl;
|
||||
LOG(Message) << "Out path : " << outFilename << std::endl;
|
||||
LOG(Message) << "Out type : " << typeName<FOut>() << std::endl;
|
||||
LOG(Message) << "#vectors : " << size << std::endl;
|
||||
LOG(Message) << "Multifile : " << (multiFile ? "yes" : "no") << std::endl;
|
||||
LOG(Message) << "Test read : " << (testRead ? "yes" : "no") << std::endl;
|
||||
if (multiFile)
|
||||
{
|
||||
for(unsigned int k = 0; k < size; ++k)
|
||||
{
|
||||
std::string outV = outFilename + "/v" + std::to_string(k) + ".bin";
|
||||
std::string inV = inFilename + "/v" + std::to_string(k) + ".bin";
|
||||
|
||||
LOG(Message) << "==== Converting vector " << k << std::endl;
|
||||
LOG(Message) << "In : " << inV << std::endl;
|
||||
LOG(Message) << "Out: " << outV << std::endl;
|
||||
// conversion
|
||||
LOG(Message) << "-- Doing conversion" << std::endl;
|
||||
makeFileDir(outV, gOut);
|
||||
binWriter.open(outV);
|
||||
binReader.open(inV);
|
||||
EigenPackIo::readHeader(record, binReader);
|
||||
EigenPackIo::writeHeader(binWriter, record);
|
||||
EigenPackIo::readElement<FIn>(bufIn, eval, k, binReader);
|
||||
EigenPackIo::writeElement<FIn, FOut>(binWriter, bufIn, eval, k, &bufOut, &testIn);
|
||||
binWriter.close();
|
||||
binReader.close();
|
||||
// read test
|
||||
if (testRead)
|
||||
{
|
||||
LOG(Message) << "-- Test read" << std::endl;
|
||||
binReader.open(outV);
|
||||
EigenPackIo::readElement<FOut>(bufOut, eval, k, binReader);
|
||||
binReader.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// conversion
|
||||
LOG(Message) << "-- Doing conversion" << std::endl;
|
||||
makeFileDir(outFilename, gOut);
|
||||
binWriter.open(outFilename);
|
||||
binReader.open(inFilename);
|
||||
EigenPackIo::readHeader(record, binReader);
|
||||
EigenPackIo::writeHeader(binWriter, record);
|
||||
for(unsigned int k = 0; k < size; ++k)
|
||||
{
|
||||
EigenPackIo::readElement<FIn>(bufIn, eval, k, binReader);
|
||||
EigenPackIo::writeElement<FIn, FOut>(binWriter, bufIn, eval, k, &bufOut, &testIn);
|
||||
}
|
||||
binWriter.close();
|
||||
binReader.close();
|
||||
// read test
|
||||
if (testRead)
|
||||
{
|
||||
LOG(Message) << "-- Test read" << std::endl;
|
||||
binReader.open(outFilename);
|
||||
EigenPackIo::readHeader(record, binReader);
|
||||
for(unsigned int k = 0; k < size; ++k)
|
||||
{
|
||||
EigenPackIo::readElement<FOut>(bufOut, eval, k, binReader);
|
||||
}
|
||||
binReader.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FOUT
|
||||
#warning "FOUT undefined (set to WilsonImplF::FermionField by default)"
|
||||
#define FOUT WilsonImplF::FermionField
|
||||
#endif
|
||||
#ifndef FIN
|
||||
#warning "FIN undefined (set to WilsonImplD::FermionField by default)"
|
||||
#define FIN WilsonImplD::FermionField
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// parse command line
|
||||
std::string outFilename, inFilename;
|
||||
unsigned int size, Ls;
|
||||
bool rb, multiFile, testRead;
|
||||
|
||||
if (argc < 8)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " <out eigenpack> <in eigenpack> <Ls> <red-black {0|1}> <#vector> <multifile {0|1}> <test read {0|1}> [Grid options]";
|
||||
std::cerr << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
outFilename = argv[1];
|
||||
inFilename = argv[2];
|
||||
Ls = std::stoi(std::string(argv[3]));
|
||||
rb = (std::string(argv[4]) != "0");
|
||||
size = std::stoi(std::string(argv[5]));
|
||||
multiFile = (std::string(argv[6]) != "0");
|
||||
testRead = (std::string(argv[7]) != "0");
|
||||
|
||||
// initialization
|
||||
Grid_init(&argc, &argv);
|
||||
initLogger();
|
||||
|
||||
// execution
|
||||
try
|
||||
{
|
||||
convert<FOUT, FIN>(outFilename, inFilename, Ls, rb, size, multiFile, testRead);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
Exceptions::abort(e);
|
||||
}
|
||||
|
||||
// epilogue
|
||||
LOG(Message) << "Grid is finalizing now" << std::endl;
|
||||
Grid_finalize();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: Hadrons/Utilities/HadronsXmlValidate.cc
|
||||
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
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 <Hadrons/Application.hpp>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace QCD;
|
||||
using namespace Hadrons;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// parse command line
|
||||
std::string parameterFileName;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "usage: " << argv[0] << " <parameter file>";
|
||||
std::cerr << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
parameterFileName = argv[1];
|
||||
|
||||
try
|
||||
{
|
||||
Application application(parameterFileName);
|
||||
|
||||
application.parseParameterFile(parameterFileName);
|
||||
auto &vm = VirtualMachine::getInstance();
|
||||
vm.getModuleGraph();
|
||||
LOG(Message) << "Application valid (check XML warnings though)"
|
||||
<< std::endl;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
Exceptions::abort(e);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
bin_PROGRAMS = HadronsXmlRun HadronsXmlValidate HadronsFermionEP64To32 HadronsContractor HadronsContractorBenchmark
|
||||
|
||||
HadronsXmlRun_SOURCES = HadronsXmlRun.cc
|
||||
HadronsXmlRun_LDADD = ../libHadrons.a ../../Grid/libGrid.a
|
||||
|
||||
HadronsXmlValidate_SOURCES = HadronsXmlValidate.cc
|
||||
HadronsXmlValidate_LDADD = ../libHadrons.a ../../Grid/libGrid.a
|
||||
|
||||
HadronsFermionEP64To32_SOURCES = EigenPackCast.cc
|
||||
HadronsFermionEP64To32_CXXFLAGS = $(AM_CXXFLAGS) -DFIN=WilsonImplD::FermionField -DFOUT=WilsonImplF::FermionField
|
||||
HadronsFermionEP64To32_LDADD = ../libHadrons.a ../../Grid/libGrid.a
|
||||
|
||||
HadronsContractor_SOURCES = Contractor.cc
|
||||
HadronsContractor_LDADD = ../libHadrons.a ../../Grid/libGrid.a
|
||||
|
||||
HadronsContractorBenchmark_SOURCES = ContractorBenchmark.cc
|
||||
HadronsContractorBenchmark_LDADD = ../libHadrons.a ../../Grid/libGrid.a
|
@ -1,10 +1,15 @@
|
||||
# additional include paths necessary to compile the C++ library
|
||||
SUBDIRS = Grid HMC Hadrons benchmarks tests
|
||||
SUBDIRS = lib benchmarks tests extras
|
||||
|
||||
include $(top_srcdir)/doxygen.inc
|
||||
|
||||
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)
|
||||
|
||||
tests-local: all
|
||||
|
5
VERSION
Normal file
5
VERSION
Normal file
@ -0,0 +1,5 @@
|
||||
Version : 0.8.0
|
||||
|
||||
- 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
|
||||
- Half precision comms
|
@ -1,48 +1,108 @@
|
||||
#include <Grid/Grid.h>
|
||||
#ifdef HAVE_LIME
|
||||
|
||||
#include "Benchmark_IO.hpp"
|
||||
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
|
||||
|
||||
using namespace Grid;
|
||||
using namespace QCD;
|
||||
typedef function<void(const string, LatticeFermion &)> WriterFn;
|
||||
typedef function<void(LatticeFermion &, const string)> ReaderFn;
|
||||
|
||||
std::string filestem(const int l)
|
||||
string filestem(const int l)
|
||||
{
|
||||
return "iobench_l" + std::to_string(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" << std::endl;
|
||||
MSG << SEP << std::endl;
|
||||
MSG << "Benchmark Lime write" << std::endl;
|
||||
MSG << SEP << std::endl;
|
||||
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)
|
||||
{
|
||||
auto mpi = GridDefaultMpi();
|
||||
std::vector<int> latt = {l*mpi[0], l*mpi[1], l*mpi[2], l*mpi[3]};
|
||||
|
||||
std::cout << "-- Local volume " << l << "^4" << std::endl;
|
||||
writeBenchmark<LatticeFermion>(latt, filestem(l), limeWrite<LatticeFermion>);
|
||||
writeBenchmark(l, limeWrite);
|
||||
}
|
||||
|
||||
MSG << "Benchmark Lime read" << std::endl;
|
||||
MSG << SEP << std::endl;
|
||||
MSG << "Benchmark Lime read" << endl;
|
||||
MSG << SEP << endl;
|
||||
for (int l = 4; l <= BENCH_IO_LMAX; l += 2)
|
||||
{
|
||||
auto mpi = GridDefaultMpi();
|
||||
std::vector<int> latt = {l*mpi[0], l*mpi[1], l*mpi[2], l*mpi[3]};
|
||||
|
||||
std::cout << "-- Local volume " << l << "^4" << std::endl;
|
||||
readBenchmark<LatticeFermion>(latt, filestem(l), limeRead<LatticeFermion>);
|
||||
readBenchmark(l, limeRead);
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#else
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user