mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-10-31 12:04:33 +00:00 
			
		
		
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			release/0.
			...
			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