From 0fb84fa34b11ef81dd4bef25661420e0a088dbef Mon Sep 17 00:00:00 2001 From: Dan H Date: Mon, 12 Mar 2018 17:03:48 -0400 Subject: [PATCH 001/126] Make compilation faster by moving print of git hash. --- lib/util/Init.cc | 7 +------ lib/util/Init.h | 1 + lib/util/version.cc | 12 ++++++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 lib/util/version.cc diff --git a/lib/util/Init.cc b/lib/util/Init.cc index b4ac14b7..45a37a02 100644 --- a/lib/util/Init.cc +++ b/lib/util/Init.cc @@ -289,12 +289,7 @@ void Grid_init(int *argc,char ***argv) std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of"< &simd, std::vector &mpi); + void printHash(void); }; #endif diff --git a/lib/util/version.cc b/lib/util/version.cc new file mode 100644 index 00000000..19759274 --- /dev/null +++ b/lib/util/version.cc @@ -0,0 +1,12 @@ +#include +#include +namespace Grid { + void printHash(){ +#ifdef GITHASH + std::cout << "Current Grid git commit hash=" << GITHASH << std::endl; +#else + std::cout << "Current Grid git commit hash is undefined. Check makefile." << std::endl; +#endif +#undef GITHASH +} +} From d86936a3deb7c1670967874c21d5afb2d9ee051d Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 16 Mar 2018 12:26:39 +0000 Subject: [PATCH 002/126] Eliminating deprecated lex_sites --- lib/lattice/Lattice_coordinate.h | 18 ------------------ tests/core/Test_main.cc | 1 - 2 files changed, 19 deletions(-) diff --git a/lib/lattice/Lattice_coordinate.h b/lib/lattice/Lattice_coordinate.h index 2e20ba17..19eceba8 100644 --- a/lib/lattice/Lattice_coordinate.h +++ b/lib/lattice/Lattice_coordinate.h @@ -52,23 +52,5 @@ namespace Grid { } }; - // LatticeCoordinate(); - // FIXME for debug; deprecate this; made obscelete by - template void lex_sites(Lattice &l){ - Real *v_ptr = (Real *)&l._odata[0]; - size_t o_len = l._grid->oSites(); - size_t v_len = sizeof(vobj)/sizeof(vRealF); - size_t vec_len = vRealF::Nsimd(); - - for(int i=0;i Date: Tue, 20 Mar 2018 18:01:32 +0000 Subject: [PATCH 003/126] Extra test for Gparity with plaquette action --- tests/forces/Test_gp_plaq_force.cc | 123 +++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 tests/forces/Test_gp_plaq_force.cc diff --git a/tests/forces/Test_gp_plaq_force.cc b/tests/forces/Test_gp_plaq_force.cc new file mode 100644 index 00000000..e121f21b --- /dev/null +++ b/tests/forces/Test_gp_plaq_force.cc @@ -0,0 +1,123 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./tests/Test_gp_rect_force.cc + + Copyright (C) 2015 + +Author: paboyle + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + See the full license in the file "LICENSE" in the top level distribution directory + *************************************************************************************/ + /* END LEGAL */ +#include + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +int main (int argc, char ** argv) +{ + Grid_init(&argc,&argv); + + std::vector latt_size = GridDefaultLatt(); + std::vector simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd()); + std::vector mpi_layout = GridDefaultMpi(); + + GridCartesian Grid(latt_size,simd_layout,mpi_layout); + GridRedBlackCartesian RBGrid(&Grid); + + int threads = GridThread::GetThreads(); + std::cout< seeds({1,2,3,4}); + + GridParallelRNG pRNG(&Grid); + pRNG.SeedFixedIntegers(std::vector({45,12,81,9})); + + LatticeGaugeField U(&Grid); + + SU3::HotConfiguration(pRNG,U); + + double beta = 1.0; + double c1 = 0.331; + + //ConjugatePlaqPlusRectangleActionR Action(beta,c1); + ConjugateWilsonGaugeActionR Action(beta); + //WilsonGaugeActionR Action(beta); + + ComplexD S = Action.S(U); + + // get the deriv of phidag MdagM phi with respect to "U" + LatticeGaugeField UdSdU(&Grid); + + Action.deriv(U,UdSdU); + + //////////////////////////////////// + // Modify the gauge field a little + //////////////////////////////////// + RealD dt = 0.0001; + + LatticeColourMatrix mommu(&Grid); + LatticeColourMatrix forcemu(&Grid); + LatticeGaugeField mom(&Grid); + LatticeGaugeField Uprime(&Grid); + + for(int mu=0;mu(mom,mommu,mu); + + // fourth order exponential approx + parallel_for(auto i=mom.begin();i(UdSdU,mu); + mommu = PeekIndex(mom,mu); + + // Update gauge action density + // U = exp(p dt) U + // dU/dt = p U + // so dSdt = trace( dUdt dSdU) = trace( p UdSdUmu ) + + dS = dS - trace(mommu*UdSdUmu)*dt*2.0; + + } + ComplexD dSpred = sum(dS); + + std::cout << GridLogMessage << " S "< Date: Tue, 20 Mar 2018 18:16:15 +0000 Subject: [PATCH 004/126] Put a username in the path --- lib/communicator/SharedMemoryMPI.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/communicator/SharedMemoryMPI.cc b/lib/communicator/SharedMemoryMPI.cc index 1fa84dfb..8eebdc0f 100644 --- a/lib/communicator/SharedMemoryMPI.cc +++ b/lib/communicator/SharedMemoryMPI.cc @@ -27,6 +27,7 @@ Author: Peter Boyle /* END LEGAL */ #include +#include namespace Grid { @@ -288,7 +289,8 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) size_t size = bytes; - sprintf(shm_name,"/myGrid_mpi3_shm_%d_%d",WorldNode,r); + struct passwd *pw = getpwuid (getuid()); + sprintf(shm_name,"/Grid_%s_mpi3_shm_%d_%d",pw->pw_name,WorldNode,r); shm_unlink(shm_name); int fd=shm_open(shm_name,O_RDWR|O_CREAT,0666); From 60b57706c4bd264b39a765835d2cff0c19722bf0 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 21 Mar 2018 13:57:30 +0000 Subject: [PATCH 005/126] Small bug fix in the shm file names --- lib/communicator/SharedMemoryMPI.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/communicator/SharedMemoryMPI.cc b/lib/communicator/SharedMemoryMPI.cc index 8eebdc0f..d534a6d9 100644 --- a/lib/communicator/SharedMemoryMPI.cc +++ b/lib/communicator/SharedMemoryMPI.cc @@ -325,7 +325,8 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) size_t size = bytes ; - sprintf(shm_name,"/Grid_mpi3_shm_%d_%d",WorldNode,r); + struct passwd *pw = getpwuid (getuid()); + sprintf(shm_name,"/Grid_%s_mpi3_shm_%d_%d",pw->pw_name,WorldNode,r); int fd=shm_open(shm_name,O_RDWR,0666); if ( fd<0 ) { perror("failed shm_open"); assert(0); } From 07fe7d0cbe4de70bbfcfe3dbe60c2cedf1b8390c Mon Sep 17 00:00:00 2001 From: paboyle Date: Wed, 21 Mar 2018 14:26:04 +0000 Subject: [PATCH 006/126] Save file in current dir; print checksums --- tests/Test_dwf_mixedcg_prec.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Test_dwf_mixedcg_prec.cc b/tests/Test_dwf_mixedcg_prec.cc index 2601b76c..0a8d6540 100644 --- a/tests/Test_dwf_mixedcg_prec.cc +++ b/tests/Test_dwf_mixedcg_prec.cc @@ -103,6 +103,27 @@ int main (int argc, char ** argv) std::cout << "Diff between mixed and regular CG: " << diff << std::endl; + std::string file1("./Propagator1"); + std::string file2("./Propagator2"); + emptyUserRecord record; + uint32_t nersc_csum; + uint32_t scidac_csuma; + uint32_t scidac_csumb; + typedef SpinColourVectorD FermionD; + typedef vSpinColourVectorD vFermionD; + + BinarySimpleMunger munge; + std::string format = getFormatString(); + BinaryIO::writeLatticeObject(result_o,file1,munge, 0, format, + nersc_csum,scidac_csuma,scidac_csumb); + + std::cout << " Mixed checksums "<(result_o_2,file1,munge, 0, format, + nersc_csum,scidac_csuma,scidac_csumb); + + std::cout << " CG checksums "< Date: Wed, 21 Mar 2018 20:38:19 -0400 Subject: [PATCH 007/126] Add dimension match check to precisionChange. --- lib/lattice/Lattice_transfer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/lattice/Lattice_transfer.h b/lib/lattice/Lattice_transfer.h index 32c15d22..44f0337d 100644 --- a/lib/lattice/Lattice_transfer.h +++ b/lib/lattice/Lattice_transfer.h @@ -652,6 +652,7 @@ vectorizeFromLexOrdArray( std::vector &in, Lattice &out) template void precisionChange(Lattice &out, const Lattice &in){ assert(out._grid->Nd() == in._grid->Nd()); + assert(out._grid->FullDimensions() == in._grid->FullDimensions()); out.checkerboard = in.checkerboard; GridBase *in_grid=in._grid; GridBase *out_grid = out._grid; From 68168bf72dccbf6e1eb89f9be8c7479bd0dc2a7d Mon Sep 17 00:00:00 2001 From: Dan H Date: Wed, 21 Mar 2018 20:51:38 -0400 Subject: [PATCH 008/126] Revert "Add dimension match check to precisionChange." This reverts commit 8f601d9b39d3635f9972fb5f7326a905780bda5f. --- lib/lattice/Lattice_transfer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/lattice/Lattice_transfer.h b/lib/lattice/Lattice_transfer.h index 44f0337d..32c15d22 100644 --- a/lib/lattice/Lattice_transfer.h +++ b/lib/lattice/Lattice_transfer.h @@ -652,7 +652,6 @@ vectorizeFromLexOrdArray( std::vector &in, Lattice &out) template void precisionChange(Lattice &out, const Lattice &in){ assert(out._grid->Nd() == in._grid->Nd()); - assert(out._grid->FullDimensions() == in._grid->FullDimensions()); out.checkerboard = in.checkerboard; GridBase *in_grid=in._grid; GridBase *out_grid = out._grid; From ccde8b817f7b906150ca581b860d25a515fd8a96 Mon Sep 17 00:00:00 2001 From: Dan H Date: Wed, 21 Mar 2018 20:58:04 -0400 Subject: [PATCH 009/126] Add dimension check to precisionChange. --- lib/lattice/Lattice_transfer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/lattice/Lattice_transfer.h b/lib/lattice/Lattice_transfer.h index 32c15d22..44f0337d 100644 --- a/lib/lattice/Lattice_transfer.h +++ b/lib/lattice/Lattice_transfer.h @@ -652,6 +652,7 @@ vectorizeFromLexOrdArray( std::vector &in, Lattice &out) template void precisionChange(Lattice &out, const Lattice &in){ assert(out._grid->Nd() == in._grid->Nd()); + assert(out._grid->FullDimensions() == in._grid->FullDimensions()); out.checkerboard = in.checkerboard; GridBase *in_grid=in._grid; GridBase *out_grid = out._grid; From 5f8225461b51ae27587a7a25685e9c823ee682f6 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 23 Mar 2018 10:37:58 +0000 Subject: [PATCH 010/126] Fencing mixedcg test propagator write. LIME is still optional in Grid --- tests/Test_dwf_mixedcg_prec.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Test_dwf_mixedcg_prec.cc b/tests/Test_dwf_mixedcg_prec.cc index 0a8d6540..84849ff9 100644 --- a/tests/Test_dwf_mixedcg_prec.cc +++ b/tests/Test_dwf_mixedcg_prec.cc @@ -103,6 +103,7 @@ int main (int argc, char ** argv) std::cout << "Diff between mixed and regular CG: " << diff << std::endl; + #ifdef HAVE_LIME std::string file1("./Propagator1"); std::string file2("./Propagator2"); emptyUserRecord record; @@ -124,6 +125,8 @@ int main (int argc, char ** argv) nersc_csum,scidac_csuma,scidac_csumb); std::cout << " CG checksums "< Date: Fri, 23 Mar 2018 11:14:23 +0000 Subject: [PATCH 011/126] Fix to pass CI tests --- tests/Test_dwf_mixedcg_prec.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Test_dwf_mixedcg_prec.cc b/tests/Test_dwf_mixedcg_prec.cc index 84849ff9..a53d8921 100644 --- a/tests/Test_dwf_mixedcg_prec.cc +++ b/tests/Test_dwf_mixedcg_prec.cc @@ -104,6 +104,8 @@ int main (int argc, char ** argv) std::cout << "Diff between mixed and regular CG: " << diff << std::endl; #ifdef HAVE_LIME + if( GridCmdOptionExists(argv,argv+argc,"--checksums") ){ + std::string file1("./Propagator1"); std::string file2("./Propagator2"); emptyUserRecord record; @@ -125,6 +127,7 @@ int main (int argc, char ** argv) nersc_csum,scidac_csuma,scidac_csumb); std::cout << " CG checksums "< Date: Fri, 23 Mar 2018 11:27:56 +0000 Subject: [PATCH 012/126] Changes in messages in test dwf mixedprec --- tests/Test_dwf_mixedcg_prec.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/Test_dwf_mixedcg_prec.cc b/tests/Test_dwf_mixedcg_prec.cc index a53d8921..92567b6f 100644 --- a/tests/Test_dwf_mixedcg_prec.cc +++ b/tests/Test_dwf_mixedcg_prec.cc @@ -49,6 +49,8 @@ int main (int argc, char ** argv) const int Ls=8; + std::cout << GridLogMessage << "::::: NB: to enable a quick bit reproducibility check use the --checksums flag. " << std::endl; + GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplexD::Nsimd()),GridDefaultMpi()); GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); @@ -90,24 +92,23 @@ int main (int argc, char ** argv) SchurDiagMooeeOperator HermOpEO(Ddwf); SchurDiagMooeeOperator HermOpEO_f(Ddwf_f); - std::cout << "Starting mixed CG" << std::endl; + std::cout << GridLogMessage << "::::::::::::: Starting mixed CG" << std::endl; MixedPrecisionConjugateGradient mCG(1.0e-8, 10000, 50, FrbGrid_f, HermOpEO_f, HermOpEO); mCG(src_o,result_o); - std::cout << "Starting regular CG" << std::endl; + std::cout << GridLogMessage << "::::::::::::: Starting regular CG" << std::endl; ConjugateGradient CG(1.0e-8,10000); CG(HermOpEO,src_o,result_o_2); LatticeFermionD diff_o(FrbGrid); RealD diff = axpy_norm(diff_o, -1.0, result_o, result_o_2); - std::cout << "Diff between mixed and regular CG: " << diff << std::endl; + std::cout << GridLogMessage << "::::::::::::: Diff between mixed and regular CG: " << diff << std::endl; #ifdef HAVE_LIME if( GridCmdOptionExists(argv,argv+argc,"--checksums") ){ std::string file1("./Propagator1"); - std::string file2("./Propagator2"); emptyUserRecord record; uint32_t nersc_csum; uint32_t scidac_csuma; @@ -121,12 +122,12 @@ int main (int argc, char ** argv) BinaryIO::writeLatticeObject(result_o,file1,munge, 0, format, nersc_csum,scidac_csuma,scidac_csumb); - std::cout << " Mixed checksums "<(result_o_2,file1,munge, 0, format, nersc_csum,scidac_csuma,scidac_csumb); - std::cout << " CG checksums "< Date: Mon, 26 Mar 2018 19:16:16 +0100 Subject: [PATCH 013/126] Lattice serialisation, just HDF5 for the moment --- lib/lattice/Lattice_transfer.h | 93 +++++++++++++++++++++++++++++++++ lib/serialisation/Hdf5IO.h | 64 ++++++++++++++++++++++- lib/serialisation/VectorUtils.h | 44 +++++++++++++++- 3 files changed, 199 insertions(+), 2 deletions(-) diff --git a/lib/lattice/Lattice_transfer.h b/lib/lattice/Lattice_transfer.h index 44f0337d..f988f310 100644 --- a/lib/lattice/Lattice_transfer.h +++ b/lib/lattice/Lattice_transfer.h @@ -599,6 +599,51 @@ unvectorizeToLexOrdArray(std::vector &out, const Lattice &in) extract1(in_vobj, out_ptrs, 0); } } + +template +typename std::enable_if::value && !isSIMDvectorized::value, void>::type +unvectorizeToRevLexOrdArray(std::vector &out, const Lattice &in) +{ + + typedef typename vobj::vector_type vtype; + + GridBase* in_grid = in._grid; + out.resize(in_grid->lSites()); + + int ndim = in_grid->Nd(); + int in_nsimd = vtype::Nsimd(); + + std::vector > in_icoor(in_nsimd); + + for(int lane=0; lane < in_nsimd; lane++){ + in_icoor[lane].resize(ndim); + in_grid->iCoorFromIindex(in_icoor[lane], lane); + } + + parallel_for(int in_oidx = 0; in_oidx < in_grid->oSites(); in_oidx++){ //loop over outer index + //Assemble vector of pointers to output elements + std::vector out_ptrs(in_nsimd); + + std::vector in_ocoor(ndim); + in_grid->oCoorFromOindex(in_ocoor, in_oidx); + + std::vector lcoor(in_grid->Nd()); + + for(int lane=0; lane < in_nsimd; lane++){ + for(int mu=0;mu_rdimensions[mu]*in_icoor[lane][mu]; + + int lex; + Lexicographic::IndexFromCoorReversed(lcoor, lex, in_grid->_ldimensions); + out_ptrs[lane] = &out[lex]; + } + + //Unpack into those ptrs + const vobj & in_vobj = in._odata[in_oidx]; + extract1(in_vobj, out_ptrs, 0); + } +} + //Copy SIMD-vectorized lattice to array of scalar objects in lexicographic order template typename std::enable_if::value @@ -648,6 +693,54 @@ vectorizeFromLexOrdArray( std::vector &in, Lattice &out) } } +template +typename std::enable_if::value + && !isSIMDvectorized::value, void>::type +vectorizeFromRevLexOrdArray( std::vector &in, Lattice &out) +{ + + typedef typename vobj::vector_type vtype; + + GridBase* grid = out._grid; + assert(in.size()==grid->lSites()); + + int ndim = grid->Nd(); + int nsimd = vtype::Nsimd(); + + std::vector > icoor(nsimd); + + for(int lane=0; lane < nsimd; lane++){ + icoor[lane].resize(ndim); + grid->iCoorFromIindex(icoor[lane],lane); + } + + parallel_for(uint64_t oidx = 0; oidx < grid->oSites(); oidx++){ //loop over outer index + //Assemble vector of pointers to output elements + std::vector ptrs(nsimd); + + std::vector ocoor(ndim); + grid->oCoorFromOindex(ocoor, oidx); + + std::vector lcoor(grid->Nd()); + + for(int lane=0; lane < nsimd; lane++){ + + for(int mu=0;mu_rdimensions[mu]*icoor[lane][mu]; + } + + int lex; + Lexicographic::IndexFromCoorReversed(lcoor, lex, grid->_ldimensions); + ptrs[lane] = &in[lex]; + } + + //pack from those ptrs + vobj vecobj; + merge1(vecobj, ptrs, 0); + out._odata[oidx] = vecobj; + } +} + //Convert a Lattice from one precision to another template void precisionChange(Lattice &out, const Lattice &in){ diff --git a/lib/serialisation/Hdf5IO.h b/lib/serialisation/Hdf5IO.h index 12625ab8..940bb11a 100644 --- a/lib/serialisation/Hdf5IO.h +++ b/lib/serialisation/Hdf5IO.h @@ -22,6 +22,8 @@ namespace Grid { + template class Lattice; + class Hdf5Writer: public Writer { public: @@ -33,6 +35,8 @@ namespace Grid template void writeDefault(const std::string &s, const U &x); template + void writeDefault(const std::string &s, const Lattice &field); + template typename std::enable_if>::is_number, void>::type writeDefault(const std::string &s, const std::vector &x); template @@ -60,6 +64,8 @@ namespace Grid template void readDefault(const std::string &s, U &output); template + void readDefault(const std::string &s, Lattice &field); + template typename std::enable_if>::is_number, void>::type readDefault(const std::string &s, std::vector &x); template @@ -98,7 +104,40 @@ namespace Grid template <> void Hdf5Writer::writeDefault(const std::string &s, const std::string &x); - + + + template + void Hdf5Writer::writeDefault(const std::string &s, const Lattice &field) + { + // alias scalar types + typedef std::vector ScalarLattice; + typedef typename U::scalar_type ScalarType; + + ScalarLattice scalField; + + unvectorizeToRevLexOrdArray(scalField, field); + + std::vector dim; + std::vector tDim; + + tensorDim(tDim, scalField[0]); + for (auto &d: field._grid->GlobalDimensions()) + { + dim.push_back(d); + } + for (auto &d: tDim) + { + dim.push_back(d); + } + + // write to file + H5NS::DataSpace dataSpace(dim.size(), dim.data()); + H5NS::DataSet dataSet; + + dataSet = group_.createDataSet(s, Hdf5Type::type(), dataSpace); + dataSet.write(scalField.data(), Hdf5Type::type()); + } + template typename std::enable_if>::is_number, void>::type Hdf5Writer::writeDefault(const std::string &s, const std::vector &x) @@ -169,6 +208,29 @@ namespace Grid template <> void Hdf5Reader::readDefault(const std::string &s, std::string &x); + template + void Hdf5Reader::readDefault(const std::string &s, Lattice &field) + { + // alias scalar types + typedef std::vector ScalarLattice; + typedef typename U::scalar_type ScalarType; + + ScalarLattice scalField; + H5NS::DataSet dataSet; + std::vector dim; + hsize_t size = 1; + + dataSet = group_.openDataSet(s); + for (auto &d: field._grid->GlobalDimensions()) + { + dim.push_back(d); + size *= d; + } + scalField.resize(size); + dataSet.read(scalField.data(), Hdf5Type::type()); + vectorizeFromRevLexOrdArray(scalField, field); + } + template typename std::enable_if>::is_number, void>::type Hdf5Reader::readDefault(const std::string &s, std::vector &x) diff --git a/lib/serialisation/VectorUtils.h b/lib/serialisation/VectorUtils.h index 6df9416d..e1095488 100644 --- a/lib/serialisation/VectorUtils.h +++ b/lib/serialisation/VectorUtils.h @@ -2,7 +2,7 @@ #define GRID_SERIALISATION_VECTORUTILS_H #include -#include +#include namespace Grid { // Pair IO utilities ///////////////////////////////////////////////////////// @@ -78,6 +78,48 @@ namespace Grid { typedef typename std::vector::type>> type; }; + template + void tensorDim(std::vector &dim, const T &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + } + + template + void tensorDim(std::vector &dim, const iScalar &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + tensorDim(dim, t._internal, false); + } + + template + void tensorDim(std::vector &dim, const iVector &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + dim.push_back(N); + tensorDim(dim, t._internal[0], false); + } + + template + void tensorDim(std::vector &dim, const iMatrix &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + dim.push_back(N); + dim.push_back(N); + tensorDim(dim, t._internal[0][0], false); + } + template typename TensorToVec::type tensorToVec(const T &t) { From 5ec903044da9fb5738e3be0c4aca41b6400dab31 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 27 Mar 2018 17:11:50 +0100 Subject: [PATCH 014/126] Serial IO code cleaning for std:: convention --- lib/serialisation/BinaryIO.cc | 17 ++++++++--------- lib/serialisation/JSON_IO.cc | 13 ++++++------- lib/serialisation/TextIO.cc | 15 +++++++-------- lib/serialisation/XmlIO.cc | 21 ++++++++++----------- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/lib/serialisation/BinaryIO.cc b/lib/serialisation/BinaryIO.cc index 7133adc0..a4d26b69 100644 --- a/lib/serialisation/BinaryIO.cc +++ b/lib/serialisation/BinaryIO.cc @@ -29,15 +29,14 @@ Author: paboyle #include using namespace Grid; -using namespace std; // Writer implementation /////////////////////////////////////////////////////// -BinaryWriter::BinaryWriter(const string &fileName) -: file_(fileName, ios::binary|ios::out) +BinaryWriter::BinaryWriter(const std::string &fileName) +: file_(fileName, std::ios::binary|std::ios::out) {} template <> -void BinaryWriter::writeDefault(const string &s, const string &x) +void BinaryWriter::writeDefault(const std::string &s, const std::string &x) { uint64_t sz = x.size(); @@ -48,20 +47,20 @@ void BinaryWriter::writeDefault(const string &s, const string &x) } } -void BinaryWriter::writeDefault(const string &s, const char *x) +void BinaryWriter::writeDefault(const std::string &s, const char *x) { - string sx(x); + std::string sx(x); writeDefault(s, sx); } // Reader implementation /////////////////////////////////////////////////////// -BinaryReader::BinaryReader(const string &fileName) -: file_(fileName, ios::binary|ios::in) +BinaryReader::BinaryReader(const std::string &fileName) +: file_(fileName, std::ios::binary|std::ios::in) {} template <> -void BinaryReader::readDefault(const string &s, string &output) +void BinaryReader::readDefault(const std::string &s, std::string &output) { uint64_t sz; diff --git a/lib/serialisation/JSON_IO.cc b/lib/serialisation/JSON_IO.cc index 6a01aa84..98edc375 100644 --- a/lib/serialisation/JSON_IO.cc +++ b/lib/serialisation/JSON_IO.cc @@ -28,11 +28,10 @@ #include using namespace Grid; -using namespace std; // Writer implementation /////////////////////////////////////////////////////// -JSONWriter::JSONWriter(const string &fileName) -: fileName_(fileName), ss_("{ ", ostringstream::ate){} +JSONWriter::JSONWriter(const std::string &fileName) +: fileName_(fileName), ss_("{ ", std::ostringstream::ate){} JSONWriter::~JSONWriter(void) { @@ -46,7 +45,7 @@ JSONWriter::~JSONWriter(void) os << std::setw(2) << json::parse(ss_.str()) << std::endl; } -void JSONWriter::push(const string &s) +void JSONWriter::push(const std::string &s) { // adding a nested object if (s.size()) @@ -90,7 +89,7 @@ namespace Grid // Reader implementation /////////////////////////////////////////////////////// -JSONReader::JSONReader(const string &fileName) +JSONReader::JSONReader(const std::string &fileName) : fileName_(fileName) { std::ifstream file(fileName_); @@ -102,7 +101,7 @@ JSONReader::JSONReader(const string &fileName) jcur_ = jobject_; } -bool JSONReader::push(const string &s) +bool JSONReader::push(const std::string &s) { if (s.size()){ jold_.push_back(jcur_); @@ -159,7 +158,7 @@ bool JSONReader::nextElement(const std::string &s) } template <> -void JSONReader::readDefault(const string &s, string &output) +void JSONReader::readDefault(const std::string &s, std::string &output) { //cout << "JSONReader::readDefault(string) : " << s<< " " << jcur_ << endl; if (s.size()){ diff --git a/lib/serialisation/TextIO.cc b/lib/serialisation/TextIO.cc index 5e27dfbc..77c45fd9 100644 --- a/lib/serialisation/TextIO.cc +++ b/lib/serialisation/TextIO.cc @@ -30,17 +30,16 @@ #include using namespace Grid; -using namespace std; #define GRID_TEXT_INDENT 2 //number of spaces for indentation of levels // Writer implementation /////////////////////////////////////////////////////// -TextWriter::TextWriter(const string &fileName) -: file_(fileName, ios::out) +TextWriter::TextWriter(const std::string &fileName) +: file_(fileName, std::ios::out) {} -void TextWriter::push(const string &s) +void TextWriter::push(const std::string &s) { level_++; }; @@ -58,16 +57,16 @@ void TextWriter::indent(void) }; // Reader implementation /////////////////////////////////////////////////////// -TextReader::TextReader(const string &fileName) +TextReader::TextReader(const std::string &fileName) { - file_.open(fileName, ios::in); + file_.open(fileName, std::ios::in); if (!file_.is_open()) { std::cout << GridLogMessage << "TextReader: Error opening file " << fileName << std::endl; exit(1);// write better error handling } } -bool TextReader::push(const string &s) +bool TextReader::push(const std::string &s) { level_++; return true; @@ -91,7 +90,7 @@ void TextReader::checkIndent(void) } if (!check) { - cerr << "TextReader: mismatch on level " << level_ << std::endl; + std::cerr << "TextReader: mismatch on level " << level_ << std::endl; exit(1); } } diff --git a/lib/serialisation/XmlIO.cc b/lib/serialisation/XmlIO.cc index 8ac7422c..1828d7fc 100644 --- a/lib/serialisation/XmlIO.cc +++ b/lib/serialisation/XmlIO.cc @@ -29,10 +29,9 @@ Author: paboyle #include using namespace Grid; -using namespace std; // Writer implementation /////////////////////////////////////////////////////// -XmlWriter::XmlWriter(const string &fileName, string toplev) : fileName_(fileName) +XmlWriter::XmlWriter(const std::string &fileName, std::string toplev) : fileName_(fileName) { if ( toplev == std::string("") ) { node_=doc_; @@ -49,7 +48,7 @@ XmlWriter::~XmlWriter(void) } } -void XmlWriter::push(const string &s) +void XmlWriter::push(const std::string &s) { node_ = node_.append_child(s.c_str()); } @@ -65,13 +64,13 @@ std::string XmlWriter::XmlString(void) return oss.str(); } -XmlReader::XmlReader(const char *xmlstring,string toplev) : fileName_("") +XmlReader::XmlReader(const char *xmlstring,std::string toplev) : fileName_("") { pugi::xml_parse_result result; result = doc_.load_string(xmlstring); if ( !result ) { - cerr << "XML error description (from char *): " << result.description() << "\nXML\n"<< xmlstring << "\n"; - cerr << "XML error offset (from char *) " << result.offset << "\nXML\n"<< xmlstring <<"\n"; + std::cerr << "XML error description (from char *): " << result.description() << "\nXML\n"<< xmlstring << "\n"; + std::cerr << "XML error offset (from char *) " << result.offset << "\nXML\n"<< xmlstring <<"\n"; abort(); } if ( toplev == std::string("") ) { @@ -82,13 +81,13 @@ XmlReader::XmlReader(const char *xmlstring,string toplev) : fileName_("") } // Reader implementation /////////////////////////////////////////////////////// -XmlReader::XmlReader(const string &fileName,string toplev) : fileName_(fileName) +XmlReader::XmlReader(const std::string &fileName,std::string toplev) : fileName_(fileName) { pugi::xml_parse_result result; result = doc_.load_file(fileName_.c_str()); if ( !result ) { - cerr << "XML error description: " << result.description() <<" "<< fileName_ <<"\n"; - cerr << "XML error offset : " << result.offset <<" "<< fileName_ <<"\n"; + std::cerr << "XML error description: " << result.description() <<" "<< fileName_ <<"\n"; + std::cerr << "XML error offset : " << result.offset <<" "<< fileName_ <<"\n"; abort(); } if ( toplev == std::string("") ) { @@ -98,7 +97,7 @@ XmlReader::XmlReader(const string &fileName,string toplev) : fileName_(fileName) } } -bool XmlReader::push(const string &s) +bool XmlReader::push(const std::string &s) { if (node_.child(s.c_str())) { @@ -133,7 +132,7 @@ bool XmlReader::nextElement(const std::string &s) } template <> -void XmlReader::readDefault(const string &s, string &output) +void XmlReader::readDefault(const std::string &s, std::string &output) { if (node_.child(s.c_str())) { From a4d8512fb8088f005e5424a8917e12a66c321e19 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 27 Mar 2018 17:55:42 +0100 Subject: [PATCH 015/126] Revert "Lattice serialisation, just HDF5 for the moment" This reverts commit 8a0cf0194f4ea42d104690b69cc43a1982ebeae0. --- lib/lattice/Lattice_transfer.h | 93 --------------------------------- lib/serialisation/Hdf5IO.h | 64 +---------------------- lib/serialisation/VectorUtils.h | 44 +--------------- 3 files changed, 2 insertions(+), 199 deletions(-) diff --git a/lib/lattice/Lattice_transfer.h b/lib/lattice/Lattice_transfer.h index f988f310..44f0337d 100644 --- a/lib/lattice/Lattice_transfer.h +++ b/lib/lattice/Lattice_transfer.h @@ -599,51 +599,6 @@ unvectorizeToLexOrdArray(std::vector &out, const Lattice &in) extract1(in_vobj, out_ptrs, 0); } } - -template -typename std::enable_if::value && !isSIMDvectorized::value, void>::type -unvectorizeToRevLexOrdArray(std::vector &out, const Lattice &in) -{ - - typedef typename vobj::vector_type vtype; - - GridBase* in_grid = in._grid; - out.resize(in_grid->lSites()); - - int ndim = in_grid->Nd(); - int in_nsimd = vtype::Nsimd(); - - std::vector > in_icoor(in_nsimd); - - for(int lane=0; lane < in_nsimd; lane++){ - in_icoor[lane].resize(ndim); - in_grid->iCoorFromIindex(in_icoor[lane], lane); - } - - parallel_for(int in_oidx = 0; in_oidx < in_grid->oSites(); in_oidx++){ //loop over outer index - //Assemble vector of pointers to output elements - std::vector out_ptrs(in_nsimd); - - std::vector in_ocoor(ndim); - in_grid->oCoorFromOindex(in_ocoor, in_oidx); - - std::vector lcoor(in_grid->Nd()); - - for(int lane=0; lane < in_nsimd; lane++){ - for(int mu=0;mu_rdimensions[mu]*in_icoor[lane][mu]; - - int lex; - Lexicographic::IndexFromCoorReversed(lcoor, lex, in_grid->_ldimensions); - out_ptrs[lane] = &out[lex]; - } - - //Unpack into those ptrs - const vobj & in_vobj = in._odata[in_oidx]; - extract1(in_vobj, out_ptrs, 0); - } -} - //Copy SIMD-vectorized lattice to array of scalar objects in lexicographic order template typename std::enable_if::value @@ -693,54 +648,6 @@ vectorizeFromLexOrdArray( std::vector &in, Lattice &out) } } -template -typename std::enable_if::value - && !isSIMDvectorized::value, void>::type -vectorizeFromRevLexOrdArray( std::vector &in, Lattice &out) -{ - - typedef typename vobj::vector_type vtype; - - GridBase* grid = out._grid; - assert(in.size()==grid->lSites()); - - int ndim = grid->Nd(); - int nsimd = vtype::Nsimd(); - - std::vector > icoor(nsimd); - - for(int lane=0; lane < nsimd; lane++){ - icoor[lane].resize(ndim); - grid->iCoorFromIindex(icoor[lane],lane); - } - - parallel_for(uint64_t oidx = 0; oidx < grid->oSites(); oidx++){ //loop over outer index - //Assemble vector of pointers to output elements - std::vector ptrs(nsimd); - - std::vector ocoor(ndim); - grid->oCoorFromOindex(ocoor, oidx); - - std::vector lcoor(grid->Nd()); - - for(int lane=0; lane < nsimd; lane++){ - - for(int mu=0;mu_rdimensions[mu]*icoor[lane][mu]; - } - - int lex; - Lexicographic::IndexFromCoorReversed(lcoor, lex, grid->_ldimensions); - ptrs[lane] = &in[lex]; - } - - //pack from those ptrs - vobj vecobj; - merge1(vecobj, ptrs, 0); - out._odata[oidx] = vecobj; - } -} - //Convert a Lattice from one precision to another template void precisionChange(Lattice &out, const Lattice &in){ diff --git a/lib/serialisation/Hdf5IO.h b/lib/serialisation/Hdf5IO.h index 940bb11a..12625ab8 100644 --- a/lib/serialisation/Hdf5IO.h +++ b/lib/serialisation/Hdf5IO.h @@ -22,8 +22,6 @@ namespace Grid { - template class Lattice; - class Hdf5Writer: public Writer { public: @@ -35,8 +33,6 @@ namespace Grid template void writeDefault(const std::string &s, const U &x); template - void writeDefault(const std::string &s, const Lattice &field); - template typename std::enable_if>::is_number, void>::type writeDefault(const std::string &s, const std::vector &x); template @@ -64,8 +60,6 @@ namespace Grid template void readDefault(const std::string &s, U &output); template - void readDefault(const std::string &s, Lattice &field); - template typename std::enable_if>::is_number, void>::type readDefault(const std::string &s, std::vector &x); template @@ -104,40 +98,7 @@ namespace Grid template <> void Hdf5Writer::writeDefault(const std::string &s, const std::string &x); - - - template - void Hdf5Writer::writeDefault(const std::string &s, const Lattice &field) - { - // alias scalar types - typedef std::vector ScalarLattice; - typedef typename U::scalar_type ScalarType; - - ScalarLattice scalField; - - unvectorizeToRevLexOrdArray(scalField, field); - - std::vector dim; - std::vector tDim; - - tensorDim(tDim, scalField[0]); - for (auto &d: field._grid->GlobalDimensions()) - { - dim.push_back(d); - } - for (auto &d: tDim) - { - dim.push_back(d); - } - - // write to file - H5NS::DataSpace dataSpace(dim.size(), dim.data()); - H5NS::DataSet dataSet; - - dataSet = group_.createDataSet(s, Hdf5Type::type(), dataSpace); - dataSet.write(scalField.data(), Hdf5Type::type()); - } - + template typename std::enable_if>::is_number, void>::type Hdf5Writer::writeDefault(const std::string &s, const std::vector &x) @@ -208,29 +169,6 @@ namespace Grid template <> void Hdf5Reader::readDefault(const std::string &s, std::string &x); - template - void Hdf5Reader::readDefault(const std::string &s, Lattice &field) - { - // alias scalar types - typedef std::vector ScalarLattice; - typedef typename U::scalar_type ScalarType; - - ScalarLattice scalField; - H5NS::DataSet dataSet; - std::vector dim; - hsize_t size = 1; - - dataSet = group_.openDataSet(s); - for (auto &d: field._grid->GlobalDimensions()) - { - dim.push_back(d); - size *= d; - } - scalField.resize(size); - dataSet.read(scalField.data(), Hdf5Type::type()); - vectorizeFromRevLexOrdArray(scalField, field); - } - template typename std::enable_if>::is_number, void>::type Hdf5Reader::readDefault(const std::string &s, std::vector &x) diff --git a/lib/serialisation/VectorUtils.h b/lib/serialisation/VectorUtils.h index e1095488..6df9416d 100644 --- a/lib/serialisation/VectorUtils.h +++ b/lib/serialisation/VectorUtils.h @@ -2,7 +2,7 @@ #define GRID_SERIALISATION_VECTORUTILS_H #include -#include +#include namespace Grid { // Pair IO utilities ///////////////////////////////////////////////////////// @@ -78,48 +78,6 @@ namespace Grid { typedef typename std::vector::type>> type; }; - template - void tensorDim(std::vector &dim, const T &t, const bool wipe = true) - { - if (wipe) - { - dim.clear(); - } - } - - template - void tensorDim(std::vector &dim, const iScalar &t, const bool wipe = true) - { - if (wipe) - { - dim.clear(); - } - tensorDim(dim, t._internal, false); - } - - template - void tensorDim(std::vector &dim, const iVector &t, const bool wipe = true) - { - if (wipe) - { - dim.clear(); - } - dim.push_back(N); - tensorDim(dim, t._internal[0], false); - } - - template - void tensorDim(std::vector &dim, const iMatrix &t, const bool wipe = true) - { - if (wipe) - { - dim.clear(); - } - dim.push_back(N); - dim.push_back(N); - tensorDim(dim, t._internal[0][0], false); - } - template typename TensorToVec::type tensorToVec(const T &t) { From c5a885dcd655a8f42114185f78fe5e821af44f2f Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Thu, 29 Mar 2018 19:57:41 +0100 Subject: [PATCH 016/126] I/O benchmark --- benchmarks/Benchmark_IO.cc | 101 +++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 benchmarks/Benchmark_IO.cc diff --git a/benchmarks/Benchmark_IO.cc b/benchmarks/Benchmark_IO.cc new file mode 100644 index 00000000..26aac7ae --- /dev/null +++ b/benchmarks/Benchmark_IO.cc @@ -0,0 +1,101 @@ +#include + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +#define MSG cout << GridLogMessage +#define SEP \ +"=============================================================================" +#ifndef BENCH_IO_LMAX +#define BENCH_IO_LMAX 40 +#endif + +typedef function WriterFn; +typedef function ReaderFn; + +string filestem(const int l) +{ + return "iobench_l" + to_string(l); +} + +void limeWrite(const string filestem, LatticeFermion &vec) +{ + emptyUserRecord record; + ScidacWriter binWriter; + + 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 latt = {l*mpi[0], l*mpi[1], l*mpi[2], l*mpi[3]}; + unique_ptr gPt(SpaceTimeGrid::makeFourDimGrid(latt, simd, mpi)); + GridCartesian *g = gPt.get(); + GridParallelRNG rng(g); + LatticeFermion vec(g); + emptyUserRecord record; + ScidacWriter binWriter; + + 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 latt = {l*mpi[0], l*mpi[1], l*mpi[2], l*mpi[3]}; + unique_ptr gPt(SpaceTimeGrid::makeFourDimGrid(latt, simd, mpi)); + GridCartesian *g = gPt.get(); + LatticeFermion vec(g); + emptyUserRecord record; + ScidacReader binReader; + + cout << "-- Local volume " << l << "^4" << endl; + read(vec, filestem(l)); +} + +int main (int argc, char ** argv) +{ + Grid_init(&argc,&argv); + + auto simd = GridDefaultSimd(Nd,vComplex::Nsimd()); + auto mpi = GridDefaultMpi(); + + int64_t threads = GridThread::GetThreads(); + MSG << "Grid is setup to use " << threads << " threads" << endl; + MSG << SEP << endl; + MSG << "Benchmark Lime write" << endl; + MSG << SEP << endl; + for (int l = 4; l <= BENCH_IO_LMAX; l += 2) + { + writeBenchmark(l, limeWrite); + } + + MSG << "Benchmark Lime read" << endl; + MSG << SEP << endl; + for (int l = 4; l <= BENCH_IO_LMAX; l += 2) + { + readBenchmark(l, limeRead); + } + + Grid_finalize(); + + return EXIT_SUCCESS; +} \ No newline at end of file From 2f5add4d5f53d449002ca100a82b7f9c9a16c572 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 30 Mar 2018 12:30:58 +0100 Subject: [PATCH 017/126] Creation of file --- lib/parallelIO/BinaryIO.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 39acf0e0..45fd522e 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -372,7 +372,7 @@ class BinaryIO { std::cout << GridLogMessage <<"IOobject: C++ read I/O " << file << " : " << iodata.size() * sizeof(fobj) << " bytes" << std::endl; std::ifstream fin; - fin.open(file, std::ios::binary | std::ios::in); + fin.open(file, std::ios::binary | std::ios::in); if (control & BINARYIO_MASTER_APPEND) { fin.seekg(-sizeof(fobj), fin.end); @@ -453,11 +453,15 @@ class BinaryIO { std::ofstream fout; fout.exceptions ( std::fstream::failbit | std::fstream::badbit ); try { - fout.open(file,std::ios::binary|std::ios::out|std::ios::in); + if (offset) { // Must already exist and contain data + fout.open(file,std::ios::binary|std::ios::out|std::ios::in); + } else { // Allow create + fout.open(file,std::ios::binary|std::ios::out); + } } catch (const std::fstream::failure& exc) { std::cout << GridLogError << "Error in opening the file " << file << " for output" < Date: Fri, 30 Mar 2018 12:41:30 +0100 Subject: [PATCH 018/126] Barrier required in parallel when we use ftell --- lib/parallelIO/IldgIO.h | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index b81d1e43..e29b1d39 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -350,26 +350,36 @@ class GridLimeWriter : public BinaryIO { // iv) fseek on FILE * to end of this disjoint section. // v) Continue writing scidac record. //////////////////////////////////////////////////////////////////// - + + GridBase *grid = field._grid; //////////////////////////////////////////// // Create record header //////////////////////////////////////////// typedef typename vobj::scalar_object sobj; int err; uint32_t nersc_csum,scidac_csuma,scidac_csumb; - uint64_t PayloadSize = sizeof(sobj) * field._grid->_gsites; + uint64_t PayloadSize = sizeof(sobj) * grid->_gsites; createLimeRecordHeader(record_name, 0, 0, PayloadSize); - + fflush(File); + // std::cout << "W sizeof(sobj)" <_gsites<Broadcast(0,(void *)&compare,sizeof(compare)); + + assert(compare == offset1 ); /////////////////////////////////////////// // Write by other means into the binary record /////////////////////////////////////////// - uint64_t offset1 = ftello(File); // std::cout << " Writing to offset "<(); BinarySimpleMunger munge; BinaryIO::writeLatticeObject(field, filename, munge, offset1, format,nersc_csum,scidac_csuma,scidac_csumb); @@ -380,7 +390,15 @@ class GridLimeWriter : public BinaryIO { fseek(File,0,SEEK_END); uint64_t offset2 = ftello(File); // std::cout << " now at offset "<Barrier(); + + ///////////////////////////////////////////////////////////// + // Check MPI-2 I/O did what we expect to file + ///////////////////////////////////////////////////////////// + assert( (offset2-offset1) == PayloadSize); err=limeWriterCloseRecord(LimeW); assert(err>=0); From ab6afd18ac2b6431544f92d147a530a7e21022b6 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 30 Mar 2018 13:39:20 +0100 Subject: [PATCH 019/126] Still compile if no LIME --- benchmarks/Benchmark_IO.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/benchmarks/Benchmark_IO.cc b/benchmarks/Benchmark_IO.cc index 26aac7ae..c8f2692a 100644 --- a/benchmarks/Benchmark_IO.cc +++ b/benchmarks/Benchmark_IO.cc @@ -1,3 +1,4 @@ +#ifdef HAVE_LIME #include using namespace std; @@ -98,4 +99,11 @@ int main (int argc, char ** argv) Grid_finalize(); return EXIT_SUCCESS; -} \ No newline at end of file +} +#else +#include +int main (int argc, char ** argv) +{ + return EXIT_SUCCESS; +} +#endif From a13c1091111d348ffe261c2c63863179d73ff2d0 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 30 Mar 2018 16:03:01 +0100 Subject: [PATCH 020/126] deterministic initialisation of field metadata --- lib/parallelIO/IldgIOtypes.h | 5 +++-- lib/parallelIO/MetaData.h | 18 ++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/parallelIO/IldgIOtypes.h b/lib/parallelIO/IldgIOtypes.h index 5b397e14..281b20f2 100644 --- a/lib/parallelIO/IldgIOtypes.h +++ b/lib/parallelIO/IldgIOtypes.h @@ -136,8 +136,9 @@ struct scidacRecord : Serializable { int, typesize, int, datacount); - scidacRecord() { version =1.0; } - + scidacRecord() + : version(1.0), recordtype(0), colors(0), spins(0), typesize(0), datacount(0) + {} }; //////////////////////// diff --git a/lib/parallelIO/MetaData.h b/lib/parallelIO/MetaData.h index ccc8b18f..55254786 100644 --- a/lib/parallelIO/MetaData.h +++ b/lib/parallelIO/MetaData.h @@ -81,18 +81,16 @@ namespace Grid { std::string, creation_date, std::string, archive_date, std::string, floating_point); - FieldMetaData(void) { - nd=4; - dimension.resize(4); - boundary.resize(4); - scidac_checksuma=0; - scidac_checksumb=0; - checksum=0; - } + // WARNING: non-initialised values might lead to twisted parallel IO + // issues, std::string are fine because they initliase to size 0 + // as per C++ standard. + FieldMetaData(void) + : nd(4), dimension(4,0), boundary(4, ""), data_start(0), + link_trace(0.), plaquette(0.), checksum(0), + scidac_checksuma(0), scidac_checksumb(0), sequence_number(0) + {} }; - - namespace QCD { using namespace Grid; From 276f113f288de9030468f84b8a0fef81a763ecbf Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 30 Mar 2018 16:17:05 +0100 Subject: [PATCH 021/126] IO uses master boss node for metadata. --- benchmarks/Benchmark_IO.cc | 7 +- lib/parallelIO/IldgIO.h | 144 ++++++++++-------- lib/qcd/hmc/checkpointers/ILDGCheckpointer.h | 4 +- tests/IO/Test_ildg_io.cc | 2 +- .../Test_dwf_compressed_lanczos_reorg.cc | 4 +- tests/solver/Test_dwf_mrhs_cg.cc | 4 +- 6 files changed, 94 insertions(+), 71 deletions(-) diff --git a/benchmarks/Benchmark_IO.cc b/benchmarks/Benchmark_IO.cc index c8f2692a..479ae037 100644 --- a/benchmarks/Benchmark_IO.cc +++ b/benchmarks/Benchmark_IO.cc @@ -1,5 +1,5 @@ -#ifdef HAVE_LIME #include +#ifdef HAVE_LIME using namespace std; using namespace Grid; @@ -23,7 +23,7 @@ string filestem(const int l) void limeWrite(const string filestem, LatticeFermion &vec) { emptyUserRecord record; - ScidacWriter binWriter; + ScidacWriter binWriter(vec._grid->IsBoss()); binWriter.open(filestem + ".bin"); binWriter.writeScidacFieldRecord(vec, record); @@ -50,7 +50,7 @@ void writeBenchmark(const int l, const WriterFn &write) GridParallelRNG rng(g); LatticeFermion vec(g); emptyUserRecord record; - ScidacWriter binWriter; + ScidacWriter binWriter(g->IsBoss()); cout << "-- Local volume " << l << "^4" << endl; random(rng, vec); @@ -101,7 +101,6 @@ int main (int argc, char ** argv) return EXIT_SUCCESS; } #else -#include int main (int argc, char ** argv) { return EXIT_SUCCESS; diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index e29b1d39..d1a684f3 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -272,8 +272,10 @@ class GridLimeReader : public BinaryIO { } }; -class GridLimeWriter : public BinaryIO { +class GridLimeWriter : public BinaryIO +{ public: + /////////////////////////////////////////////////// // FIXME: format for RNG? Now just binary out instead // FIXME: collective calls or not ? @@ -282,17 +284,24 @@ class GridLimeWriter : public BinaryIO { FILE *File; LimeWriter *LimeW; std::string filename; - + bool boss_node; + GridLimeWriter( bool isboss = true) { + boss_node = isboss; + } void open(const std::string &_filename) { filename= _filename; - File = fopen(filename.c_str(), "w"); - LimeW = limeCreateWriter(File); assert(LimeW != NULL ); + if ( boss_node ) { + File = fopen(filename.c_str(), "w"); + LimeW = limeCreateWriter(File); assert(LimeW != NULL ); + } } ///////////////////////////////////////////// // Close the file ///////////////////////////////////////////// void close(void) { - fclose(File); + if ( boss_node ) { + fclose(File); + } // limeDestroyWriter(LimeW); } /////////////////////////////////////////////////////// @@ -300,10 +309,12 @@ class GridLimeWriter : public BinaryIO { /////////////////////////////////////////////////////// int createLimeRecordHeader(std::string message, int MB, int ME, size_t PayloadSize) { - LimeRecordHeader *h; - h = limeCreateHeader(MB, ME, const_cast(message.c_str()), PayloadSize); - assert(limeWriteRecordHeader(h, LimeW) >= 0); - limeDestroyHeader(h); + if ( boss_node ) { + LimeRecordHeader *h; + h = limeCreateHeader(MB, ME, const_cast(message.c_str()), PayloadSize); + assert(limeWriteRecordHeader(h, LimeW) >= 0); + limeDestroyHeader(h); + } return LIME_SUCCESS; } //////////////////////////////////////////// @@ -312,28 +323,31 @@ class GridLimeWriter : public BinaryIO { template void writeLimeObject(int MB,int ME,serialisable_object &object,std::string object_name,std::string record_name) { - std::string xmlstring; - { - XmlWriter WR("",""); - write(WR,object_name,object); - xmlstring = WR.XmlString(); + if ( boss_node ) { + std::string xmlstring; + { + XmlWriter WR("",""); + write(WR,object_name,object); + xmlstring = WR.XmlString(); + } + // std::cout << "WriteLimeObject" << record_name <(record_name.c_str()), nbytes); + assert(h!= NULL); + + err=limeWriteRecordHeader(h, LimeW); assert(err>=0); + err=limeWriteRecordData(&xmlstring[0], &nbytes, LimeW); assert(err>=0); + err=limeWriterCloseRecord(LimeW); assert(err>=0); + limeDestroyHeader(h); } - // std::cout << "WriteLimeObject" << record_name <(record_name.c_str()), nbytes); - assert(h!= NULL); - - err=limeWriteRecordHeader(h, LimeW); assert(err>=0); - err=limeWriteRecordData(&xmlstring[0], &nbytes, LimeW); assert(err>=0); - err=limeWriterCloseRecord(LimeW); assert(err>=0); - limeDestroyHeader(h); - // std::cout << " File offset is now"< void writeLimeLatticeBinaryObject(Lattice &field,std::string record_name) { @@ -352,6 +366,8 @@ class GridLimeWriter : public BinaryIO { //////////////////////////////////////////////////////////////////// GridBase *grid = field._grid; + assert(boss_node == field._grid->IsBoss() ); + //////////////////////////////////////////// // Create record header //////////////////////////////////////////// @@ -359,8 +375,10 @@ class GridLimeWriter : public BinaryIO { int err; uint32_t nersc_csum,scidac_csuma,scidac_csumb; uint64_t PayloadSize = sizeof(sobj) * grid->_gsites; - createLimeRecordHeader(record_name, 0, 0, PayloadSize); - fflush(File); + if ( boss_node ) { + createLimeRecordHeader(record_name, 0, 0, PayloadSize); + fflush(File); + } // std::cout << "W sizeof(sobj)" <_gsites<Broadcast(0,(void *)&compare,sizeof(compare)); - - assert(compare == offset1 ); + uint64_t offset1; + if ( boss_node ) { + offset1 = ftello(File); + } + grid->Broadcast(0,(void *)&offset1,sizeof(offset1)); /////////////////////////////////////////// - // Write by other means into the binary record + // The above is collective. Write by other means into the binary record /////////////////////////////////////////// - std::string format = getFormatString(); BinarySimpleMunger munge; BinaryIO::writeLatticeObject(field, filename, munge, offset1, format,nersc_csum,scidac_csuma,scidac_csumb); @@ -387,21 +403,19 @@ class GridLimeWriter : public BinaryIO { /////////////////////////////////////////// // Wind forward and close the record /////////////////////////////////////////// - fseek(File,0,SEEK_END); - uint64_t offset2 = ftello(File); // std::cout << " now at offset "<Barrier(); + if ( boss_node ) { + fseek(File,0,SEEK_END); + uint64_t offset2 = ftello(File); // std::cout << " now at offset "<=0); + if ( boss_node ) { + err=limeWriterCloseRecord(LimeW); assert(err>=0); + } //////////////////////////////////////// // Write checksum element, propagaing forward from the BinaryIO // Always pair a checksum with a binary object, and close message @@ -411,21 +425,26 @@ class GridLimeWriter : public BinaryIO { std::stringstream streamb; streamb << std::hex << scidac_csumb; checksum.suma= streama.str(); checksum.sumb= streamb.str(); - // std::cout << GridLogMessage<<" writing scidac checksums "< - void writeScidacFileRecord(GridBase *grid,SerialisableUserFile &_userFile) - { - scidacFile _scidacFile(grid); - writeLimeObject(1,0,_scidacFile,_scidacFile.SerialisableClassName(),std::string(SCIDAC_PRIVATE_FILE_XML)); - writeLimeObject(0,1,_userFile,_userFile.SerialisableClassName(),std::string(SCIDAC_FILE_XML)); - } + ScidacWriter(bool isboss =true ) : GridLimeWriter(isboss) { }; + + template + void writeScidacFileRecord(GridBase *grid,SerialisableUserFile &_userFile) + { + scidacFile _scidacFile(grid); + if ( this->boss_node ) { + writeLimeObject(1,0,_scidacFile,_scidacFile.SerialisableClassName(),std::string(SCIDAC_PRIVATE_FILE_XML)); + writeLimeObject(0,1,_userFile,_userFile.SerialisableClassName(),std::string(SCIDAC_FILE_XML)); + } + } //////////////////////////////////////////////// // Write generic lattice field in scidac format //////////////////////////////////////////////// @@ -446,9 +465,12 @@ class ScidacWriter : public GridLimeWriter { ////////////////////////////////////////////// // Fill the Lime file record by record ////////////////////////////////////////////// - writeLimeObject(1,0,header ,std::string("FieldMetaData"),std::string(GRID_FORMAT)); // Open message - writeLimeObject(0,0,_userRecord,_userRecord.SerialisableClassName(),std::string(SCIDAC_RECORD_XML)); - writeLimeObject(0,0,_scidacRecord,_scidacRecord.SerialisableClassName(),std::string(SCIDAC_PRIVATE_RECORD_XML)); + if ( this->boss_node ) { + writeLimeObject(1,0,header ,std::string("FieldMetaData"),std::string(GRID_FORMAT)); // Open message + writeLimeObject(0,0,_userRecord,_userRecord.SerialisableClassName(),std::string(SCIDAC_RECORD_XML)); + writeLimeObject(0,0,_scidacRecord,_scidacRecord.SerialisableClassName(),std::string(SCIDAC_PRIVATE_RECORD_XML)); + } + // Collective call writeLimeLatticeBinaryObject(field,std::string(ILDG_BINARY_DATA)); // Closes message with checksum } }; @@ -515,6 +537,8 @@ class ScidacReader : public GridLimeReader { class IldgWriter : public ScidacWriter { public: + + IldgWriter(bool isboss) : ScidacWriter(isboss) {}; /////////////////////////////////// // A little helper diff --git a/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h b/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h index 3bcdc77a..9bcc33df 100644 --- a/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h +++ b/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h @@ -74,10 +74,10 @@ class ILDGHmcCheckpointer : public BaseHmcCheckpointer { if ((traj % Params.saveInterval) == 0) { std::string config, rng; this->build_filenames(traj, Params, config, rng); - + GridBase *grid = U._grid; uint32_t nersc_csum,scidac_csuma,scidac_csumb; BinaryIO::writeRNG(sRNG, pRNG, rng, 0,nersc_csum,scidac_csuma,scidac_csumb); - IldgWriter _IldgWriter; + IldgWriter _IldgWriter(grid->IsBoss()); _IldgWriter.open(config); _IldgWriter.writeConfiguration(U, traj, config, config); _IldgWriter.close(); diff --git a/tests/IO/Test_ildg_io.cc b/tests/IO/Test_ildg_io.cc index 6aac2e38..55dd93b8 100644 --- a/tests/IO/Test_ildg_io.cc +++ b/tests/IO/Test_ildg_io.cc @@ -79,7 +79,7 @@ int main (int argc, char ** argv) std::cout <subspace.size()==nbasis); emptyUserRecord record; - Grid::QCD::ScidacWriter WR; + Grid::QCD::ScidacWriter WR(this->_FineGrid->IsBoss()); WR.open(evecs_file); for(int k=0;ksubspace[k],record); @@ -96,7 +96,7 @@ public: { int n = this->evec_coarse.size(); emptyUserRecord record; - Grid::QCD::ScidacWriter WR; + Grid::QCD::ScidacWriter WR(this->_CoarseGrid->IsBoss()); WR.open(evecs_file); for(int k=0;kevec_coarse[k],record); diff --git a/tests/solver/Test_dwf_mrhs_cg.cc b/tests/solver/Test_dwf_mrhs_cg.cc index 207e1331..72ba3d26 100644 --- a/tests/solver/Test_dwf_mrhs_cg.cc +++ b/tests/solver/Test_dwf_mrhs_cg.cc @@ -114,7 +114,7 @@ int main (int argc, char ** argv) { FGrid->Barrier(); - ScidacWriter _ScidacWriter; + ScidacWriter _ScidacWriter(FGrid->IsBoss()); _ScidacWriter.open(file); std::cout << GridLogMessage << "****************************************************************** "<IsBoss()); _ScidacWriter.open(filefn.str()); _ScidacWriter.writeScidacFieldRecord(src[n],record); _ScidacWriter.close(); From 68e6a58f123a6da1f540b156f61e8d5b2f8c61d7 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 3 Apr 2018 17:42:21 +0100 Subject: [PATCH 022/126] Hadrons: several Lanczos fixes and improvements --- extras/Hadrons/EigenPack.hpp | 53 +++++++++++++------ .../Modules/MIO/LoadCoarseEigenPack.hpp | 11 +++- .../Modules/MSolver/LocalCoherenceLanczos.hpp | 15 +++--- .../iterative/LocalCoherenceLanczos.h | 8 +-- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index d27e35b9..08811107 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -152,55 +152,78 @@ public: evecCoarse.resize(sizeCoarse, gridCoarse); } - virtual void read(const std::string fileStem, const int traj = -1) + void readFine(const std::string fileStem, const int traj = -1) { std::string evecFineFilename, evalFineFilename; std::string evecCoarseFilename, evalCoarseFilename; this->makeFilenames(evecFineFilename, evalFineFilename, fileStem + "_fine", traj); - this->makeFilenames(evecCoarseFilename, evalCoarseFilename, - fileStem + "_coarse", traj); XmlReader xmlFineReader(evalFineFilename); - XmlReader xmlCoarseReader(evalCoarseFilename); LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '" << evecFineFilename << "'" << std::endl; this->basicRead(this->evec, evecFineFilename, this->evec.size()); - LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" - << evecCoarseFilename << "'" << std::endl; - this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); LOG(Message) << "Reading " << this->eval.size() << " fine eigenvalues from '" << evalFineFilename << "'" << std::endl; Grid::read(xmlFineReader, "evals", this->eval); + } + + void readCoarse(const std::string fileStem, const int traj = -1) + { + std::string evecCoarseFilename, evalCoarseFilename; + + this->makeFilenames(evecCoarseFilename, evalCoarseFilename, + fileStem + "_coarse", traj); + XmlReader xmlCoarseReader(evalCoarseFilename); + LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" + << evecCoarseFilename << "'" << std::endl; + this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); LOG(Message) << "Reading " << evalCoarse.size() << " coarse eigenvalues from '" << evalCoarseFilename << "'" << std::endl; Grid::read(xmlCoarseReader, "evals", evalCoarse); } - virtual void write(const std::string fileStem, const int traj = -1) + virtual void read(const std::string fileStem, const int traj = -1) + { + readFine(fileStem, traj); + readCoarse(fileStem, traj); + } + + void writeFine(const std::string fileStem, const int traj = -1) { std::string evecFineFilename, evalFineFilename; - std::string evecCoarseFilename, evalCoarseFilename; this->makeFilenames(evecFineFilename, evalFineFilename, fileStem + "_fine", traj); - this->makeFilenames(evecCoarseFilename, evalCoarseFilename, - fileStem + "_coarse", traj); XmlWriter xmlFineWriter(evalFineFilename); - XmlWriter xmlCoarseWriter(evalCoarseFilename); LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '" << evecFineFilename << "'" << std::endl; this->basicWrite(evecFineFilename, this->evec, this->evec.size()); - LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" - << evecCoarseFilename << "'" << std::endl; - this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); LOG(Message) << "Writing " << this->eval.size() << " fine eigenvalues to '" << evalFineFilename << "'" << std::endl; Grid::write(xmlFineWriter, "evals", this->eval); + } + + void writeCoarse(const std::string fileStem, const int traj = -1) + { + std::string evecCoarseFilename, evalCoarseFilename; + + this->makeFilenames(evecCoarseFilename, evalCoarseFilename, + fileStem + "_coarse", traj); + XmlWriter xmlCoarseWriter(evalCoarseFilename); + LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" + << evecCoarseFilename << "'" << std::endl; + this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); LOG(Message) << "Writing " << evalCoarse.size() << " coarse eigenvalues to '" << evalCoarseFilename << "'" << std::endl; Grid::write(xmlCoarseWriter, "evals", evalCoarse); } + + virtual void write(const std::string fileStem, const int traj = -1) + { + writeFine(fileStem, traj); + writeCoarse(fileStem, traj); + } }; template diff --git a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp index 77c3a7ee..b88844f4 100644 --- a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp @@ -56,6 +56,9 @@ class TLoadCoarseEigenPack: public Module { public: typedef CoarseEigenPack BasePack; + template + using iImplScalar = iScalar>>; + typedef iImplScalar SiteComplex; public: // constructor TLoadCoarseEigenPack(const std::string name); @@ -114,9 +117,15 @@ void TLoadCoarseEigenPack::setup(void) template void TLoadCoarseEigenPack::execute(void) { - auto &epack = envGetDerived(BasePack, Pack, getName()); + auto cg = env().getCoarseGrid(par().blockSize, par().Ls); + auto &epack = envGetDerived(BasePack, Pack, getName()); + Lattice dummy(cg); epack.read(par().filestem, vm().getTrajectory()); + LOG(Message) << "Block Gramm-Schmidt pass 1"<< std::endl; + blockOrthogonalise(dummy, epack.evec); + LOG(Message) << "Block Gramm-Schmidt pass 2"<< std::endl; + blockOrthogonalise(dummy, epack.evec); } END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index 80717f32..60b897c8 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -125,19 +125,18 @@ void TLocalCoherenceLanczos::setup(void) env().createCoarseGrid(blockSize, Ls); - auto cg = env().getCoarseGrid(blockSize, Ls); - auto cgrb = env().getRbCoarseGrid(blockSize, Ls); - int cNm = (par().doCoarse) ? par().coarseParams.Nm : 0; + auto cg = env().getCoarseGrid(blockSize, Ls); + int cNm = (par().doCoarse) ? par().coarseParams.Nm : 0; LOG(Message) << "Coarse grid: " << cg->GlobalDimensions() << std::endl; envCreateDerived(BasePack, CoarsePack, getName(), Ls, - par().fineParams.Nm, cNm, env().getRbGrid(Ls), cgrb); + par().fineParams.Nm, cNm, env().getRbGrid(Ls), cg); auto &epack = envGetDerived(BasePack, CoarsePack, getName()); envTmp(SchurFMat, "mat", Ls, envGet(FMat, par().action)); envGetTmp(SchurFMat, mat); - envTmp(LCL, "solver", Ls, env().getRbGrid(Ls), cgrb, mat, + envTmp(LCL, "solver", Ls, env().getRbGrid(Ls), cg, mat, Odd, epack.evec, epack.evecCoarse, epack.eval, epack.evalCoarse); } @@ -157,6 +156,10 @@ void TLocalCoherenceLanczos::execute(void) finePar.resid,finePar.MaxIt, finePar.betastp, finePar.MinRes); solver.testFine(finePar.resid*100.0); + if (!par().output.empty()) + { + epack.writeFine(par().output, vm().getTrajectory()); + } if (par().doCoarse) { LOG(Message) << "Orthogonalising" << std::endl; @@ -173,7 +176,7 @@ void TLocalCoherenceLanczos::execute(void) } if (!par().output.empty()) { - epack.write(par().output, vm().getTrajectory()); + epack.writeCoarse(par().output, vm().getTrajectory()); } } diff --git a/lib/algorithms/iterative/LocalCoherenceLanczos.h b/lib/algorithms/iterative/LocalCoherenceLanczos.h index 0c7f4f65..66ded6eb 100644 --- a/lib/algorithms/iterative/LocalCoherenceLanczos.h +++ b/lib/algorithms/iterative/LocalCoherenceLanczos.h @@ -284,9 +284,11 @@ public: }; void Orthogonalise(void ) { - CoarseScalar InnerProd(_CoarseGrid); - blockOrthogonalise(InnerProd,subspace);std::cout << GridLogMessage <<" Gramm-Schmidt pass 1"< static RealD normalise(T& v) From 0260bc77055bcb1531cd2de091f0e6ba9c8a18e2 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 3 Apr 2018 18:55:46 +0100 Subject: [PATCH 023/126] Hadrons: eigen pack writing only for boss node --- extras/Hadrons/EigenPack.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 08811107..2bd3b622 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -115,7 +115,7 @@ protected: const unsigned int size) { emptyUserRecord record; - ScidacWriter binWriter; + ScidacWriter binWriter(evec[0]._grid->IsBoss()); binWriter.open(filename); for(int k = 0; k < size; ++k) From fb62035aa099e4b37fe388f437db099c92904f85 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 3 Apr 2018 19:49:11 +0100 Subject: [PATCH 024/126] Hadrons: do not create RB coarse grids --- extras/Hadrons/Environment.cc | 28 ---------------------------- extras/Hadrons/Environment.hpp | 4 ---- 2 files changed, 32 deletions(-) diff --git a/extras/Hadrons/Environment.cc b/extras/Hadrons/Environment.cc index 9c9618f7..35bb4648 100644 --- a/extras/Hadrons/Environment.cc +++ b/extras/Hadrons/Environment.cc @@ -106,14 +106,10 @@ void Environment::createCoarseGrid(const std::vector &blockSize, gridCoarse4d_[key4d].reset( SpaceTimeGrid::makeFourDimGrid(coarseDim, GridDefaultSimd(nd, vComplex::Nsimd()), GridDefaultMpi())); - gridCoarseRb4d_[key4d].reset( - SpaceTimeGrid::makeFourDimRedBlackGrid(gridCoarse4d_[key4d].get())); if (Ls > 1) { gridCoarse5d_[key5d].reset( SpaceTimeGrid::makeFiveDimGrid(cLs, gridCoarse4d_[key4d].get())); - gridCoarseRb5d_[key5d].reset( - SpaceTimeGrid::makeFiveDimRedBlackGrid(cLs, gridCoarse4d_[key4d].get())); } } @@ -179,30 +175,6 @@ GridCartesian * Environment::getCoarseGrid( } } -GridRedBlackCartesian * Environment::getRbCoarseGrid( - const std::vector &blockSize, const unsigned int Ls) const -{ - auto key = blockSize; - - try - { - if (Ls == 1) - { - key.resize(getNd()); - return gridCoarseRb4d_.at(key).get(); - } - else - { - key.push_back(Ls); - return gridCoarseRb5d_.at(key).get(); - } - } - catch(std::out_of_range &) - { - HADRON_ERROR(Definition, "no coarse red-black grid with Ls= " + std::to_string(Ls)); - } -} - unsigned int Environment::getNd(void) const { return nd_; diff --git a/extras/Hadrons/Environment.hpp b/extras/Hadrons/Environment.hpp index 0fb81250..f624f36e 100644 --- a/extras/Hadrons/Environment.hpp +++ b/extras/Hadrons/Environment.hpp @@ -92,8 +92,6 @@ public: GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const; GridCartesian * getCoarseGrid(const std::vector &blockSize, const unsigned int Ls = 1) const; - GridRedBlackCartesian * getRbCoarseGrid(const std::vector &blockSize, - const unsigned int Ls = 1) const; std::vector getDim(void) const; int getDim(const unsigned int mu) const; unsigned long int getLocalVolume(void) const; @@ -166,9 +164,7 @@ private: GridRbPt gridRb4d_; std::map gridRb5d_; std::map, GridPt> gridCoarse4d_; - std::map, GridRbPt> gridCoarseRb4d_; std::map, GridPt> gridCoarse5d_; - std::map, GridRbPt> gridCoarseRb5d_; unsigned int nd_; // random number generator RngPt rng4d_; From d3f857b1c9391fe2abc2b2153dc9e0ac7d1d3ff2 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Wed, 4 Apr 2018 16:36:37 +0100 Subject: [PATCH 025/126] Hadrons: proper metadata for eigenpacks --- extras/Hadrons/EigenPack.hpp | 70 +++++++++++++------ extras/Hadrons/Module.hpp | 21 +++++- .../Modules/MSolver/LocalCoherenceLanczos.hpp | 10 +-- lib/parallelIO/IldgIO.h | 2 +- lib/serialisation/MacroMagic.h | 2 +- lib/serialisation/XmlIO.cc | 14 +++- lib/serialisation/XmlIO.h | 4 +- 7 files changed, 89 insertions(+), 34 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 2bd3b622..df180e9b 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -44,9 +44,23 @@ class EigenPack { public: typedef F Field; + struct PackRecord: Serializable + { + GRID_SERIALIZABLE_CLASS_MEMBERS(PackRecord, + std::string, operatorPar, + std::string, solverPar); + }; + struct VecRecord: Serializable + { + GRID_SERIALIZABLE_CLASS_MEMBERS(VecRecord, + unsigned int, index, + double, eval); + VecRecord(void): index(0), eval(0.) {} + }; public: std::vector eval; std::vector evec; + PackRecord record; public: EigenPack(void) = default; virtual ~EigenPack(void) = default; @@ -68,10 +82,10 @@ public: makeFilenames(evecFilename, evalFilename, fileStem, traj); XmlReader xmlReader(evalFilename); - basicRead(evec, evecFilename, evec.size()); LOG(Message) << "Reading " << eval.size() << " eigenvalues from '" << evalFilename << "'" << std::endl; Grid::read(xmlReader, "evals", eval); + basicRead(evec, evecFilename, evec.size()); } virtual void write(const std::string fileStem, const int traj = -1) @@ -80,10 +94,10 @@ public: makeFilenames(evecFilename, evalFilename, fileStem, traj); XmlWriter xmlWriter(evalFilename); - basicWrite(evecFilename, evec, evec.size()); LOG(Message) << "Writing " << eval.size() << " eigenvalues to '" << evalFilename << "'" << std::endl; Grid::write(xmlWriter, "evals", eval); + basicWrite(evecFilename, evec, evec.size()); } protected: void makeFilenames(std::string &evecFilename, std::string &evalFilename, @@ -96,31 +110,43 @@ protected: } template - static void basicRead(std::vector &evec, const std::string filename, - const unsigned int size) + void basicRead(std::vector &evec, const std::string filename, + const unsigned int size) { - emptyUserRecord record; ScidacReader binReader; binReader.open(filename); + binReader.readScidacFileRecord(evec[0]._grid, record); for(int k = 0; k < size; ++k) { - binReader.readScidacFieldRecord(evec[k], record); + VecRecord vecRecord; + + binReader.readScidacFieldRecord(evec[k], vecRecord); + if (vecRecord.index != k) + { + HADRON_ERROR(Io, "Eigenvector " + std::to_string(k) + " has a" + + " wrong index (expected " + std::to_string(vecRecord.index) + + ") in file '" + filename + "'"); + } } binReader.close(); } template - static void basicWrite(const std::string filename, std::vector &evec, - const unsigned int size) + void basicWrite(const std::string filename, std::vector &evec, + const unsigned int size) { - emptyUserRecord record; ScidacWriter binWriter(evec[0]._grid->IsBoss()); binWriter.open(filename); + binWriter.writeScidacFileRecord(evec[0]._grid, record); for(int k = 0; k < size; ++k) { - binWriter.writeScidacFieldRecord(evec[k], record); + VecRecord vecRecord; + + vecRecord.index = k; + vecRecord.eval = eval[k]; + binWriter.writeScidacFieldRecord(evec[k], vecRecord); } binWriter.close(); } @@ -160,12 +186,12 @@ public: this->makeFilenames(evecFineFilename, evalFineFilename, fileStem + "_fine", traj); XmlReader xmlFineReader(evalFineFilename); - LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '" - << evecFineFilename << "'" << std::endl; - this->basicRead(this->evec, evecFineFilename, this->evec.size()); LOG(Message) << "Reading " << this->eval.size() << " fine eigenvalues from '" << evalFineFilename << "'" << std::endl; Grid::read(xmlFineReader, "evals", this->eval); + LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '" + << evecFineFilename << "'" << std::endl; + this->basicRead(this->evec, evecFineFilename, this->evec.size()); } void readCoarse(const std::string fileStem, const int traj = -1) @@ -175,12 +201,12 @@ public: this->makeFilenames(evecCoarseFilename, evalCoarseFilename, fileStem + "_coarse", traj); XmlReader xmlCoarseReader(evalCoarseFilename); - LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" - << evecCoarseFilename << "'" << std::endl; - this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); LOG(Message) << "Reading " << evalCoarse.size() << " coarse eigenvalues from '" << evalCoarseFilename << "'" << std::endl; Grid::read(xmlCoarseReader, "evals", evalCoarse); + LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" + << evecCoarseFilename << "'" << std::endl; + this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); } virtual void read(const std::string fileStem, const int traj = -1) @@ -196,12 +222,12 @@ public: this->makeFilenames(evecFineFilename, evalFineFilename, fileStem + "_fine", traj); XmlWriter xmlFineWriter(evalFineFilename); - LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '" - << evecFineFilename << "'" << std::endl; - this->basicWrite(evecFineFilename, this->evec, this->evec.size()); LOG(Message) << "Writing " << this->eval.size() << " fine eigenvalues to '" << evalFineFilename << "'" << std::endl; Grid::write(xmlFineWriter, "evals", this->eval); + LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '" + << evecFineFilename << "'" << std::endl; + this->basicWrite(evecFineFilename, this->evec, this->evec.size()); } void writeCoarse(const std::string fileStem, const int traj = -1) @@ -211,12 +237,12 @@ public: this->makeFilenames(evecCoarseFilename, evalCoarseFilename, fileStem + "_coarse", traj); XmlWriter xmlCoarseWriter(evalCoarseFilename); - LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" - << evecCoarseFilename << "'" << std::endl; - this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); LOG(Message) << "Writing " << evalCoarse.size() << " coarse eigenvalues to '" << evalCoarseFilename << "'" << std::endl; Grid::write(xmlCoarseWriter, "evals", evalCoarse); + LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" + << evecCoarseFilename << "'" << std::endl; + this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); } virtual void write(const std::string fileStem, const int traj = -1) diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 85c27472..df13b8cb 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -172,6 +172,8 @@ public: // parse parameters virtual void parseParameters(XmlReader &reader, const std::string name) = 0; virtual void saveParameters(XmlWriter &writer, const std::string name) = 0; + // parameter string + virtual std::string parString(void) const = 0; // setup virtual void setup(void) {}; virtual void execute(void) = 0; @@ -200,9 +202,11 @@ public: // parse parameters virtual void parseParameters(XmlReader &reader, const std::string name); virtual void saveParameters(XmlWriter &writer, const std::string name); + // parameter string + virtual std::string parString(void) const; // parameter access - const P & par(void) const; - void setPar(const P &par); + const P & par(void) const; + void setPar(const P &par); private: P par_; }; @@ -225,6 +229,8 @@ public: push(writer, "options"); pop(writer); }; + // parameter string (empty) + virtual std::string parString(void) const {return "";}; }; /****************************************************************************** @@ -247,6 +253,17 @@ void Module

::saveParameters(XmlWriter &writer, const std::string name) write(writer, name, par_); } +template +std::string Module

::parString(void) const +{ + std::string xmlstring; + XmlWriter writer("",""); + + write(writer, par_.SerialisableClassName(), par_); + + return writer.string(); +} + template const P & Module

::par(void) const { diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index 60b897c8..f4333f80 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -148,6 +148,8 @@ void TLocalCoherenceLanczos::execute(void) auto &coarsePar = par().coarseParams; auto &epack = envGetDerived(BasePack, CoarsePack, getName()); + epack.record.operatorPar = vm().getModule(par().action)->parString(); + epack.record.solverPar = parString(); envGetTmp(LCL, solver); LOG(Message) << "Performing fine grid IRL -- Nstop= " << finePar.Nstop << ", Nk= " << finePar.Nk << ", Nm= " @@ -173,10 +175,10 @@ void TLocalCoherenceLanczos::execute(void) coarsePar.MinRes); solver.testCoarse(coarsePar.resid*100.0, par().smoother, par().coarseRelaxTol); - } - if (!par().output.empty()) - { - epack.writeCoarse(par().output, vm().getTrajectory()); + if (!par().output.empty()) + { + epack.writeCoarse(par().output, vm().getTrajectory()); + } } } diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index d1a684f3..9a5271d1 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -328,7 +328,7 @@ class GridLimeWriter : public BinaryIO { XmlWriter WR("",""); write(WR,object_name,object); - xmlstring = WR.XmlString(); + xmlstring = WR.docString(); } // std::cout << "WriteLimeObject" << record_name <\ static inline void write(Writer &WR,const std::string &s, const cname &obj){ \ diff --git a/lib/serialisation/XmlIO.cc b/lib/serialisation/XmlIO.cc index 1828d7fc..b0d463c5 100644 --- a/lib/serialisation/XmlIO.cc +++ b/lib/serialisation/XmlIO.cc @@ -44,7 +44,7 @@ XmlWriter::XmlWriter(const std::string &fileName, std::string toplev) : fileName XmlWriter::~XmlWriter(void) { if ( fileName_ != std::string("") ) { - doc_.save_file(fileName_.c_str(), " "); + doc_.save_file(fileName_.c_str(), indent_.c_str()); } } @@ -57,10 +57,18 @@ void XmlWriter::pop(void) { node_ = node_.parent(); } -std::string XmlWriter::XmlString(void) + +std::string XmlWriter::docString(void) { std::ostringstream oss; - doc_.save(oss); + doc_.save(oss, indent_.c_str()); + return oss.str(); +} + +std::string XmlWriter::string(void) +{ + std::ostringstream oss; + doc_.save(oss, indent_.c_str(), pugi::format_default | pugi::format_no_declaration); return oss.str(); } diff --git a/lib/serialisation/XmlIO.h b/lib/serialisation/XmlIO.h index e37eb8d9..c12ef6e5 100644 --- a/lib/serialisation/XmlIO.h +++ b/lib/serialisation/XmlIO.h @@ -55,8 +55,10 @@ namespace Grid void writeDefault(const std::string &s, const U &x); template void writeDefault(const std::string &s, const std::vector &x); - std::string XmlString(void); + std::string docString(void); + std::string string(void); private: + const std::string indent_{" "}; pugi::xml_document doc_; pugi::xml_node node_; std::string fileName_; From ccfc0a5a890119c9b8a7e6f772c530810e15eb88 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Wed, 4 Apr 2018 17:19:22 +0100 Subject: [PATCH 026/126] Hadrons: better string representation of module parameters --- extras/Hadrons/Module.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index df13b8cb..08cf49a2 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -256,12 +256,11 @@ void Module

::saveParameters(XmlWriter &writer, const std::string name) template std::string Module

::parString(void) const { - std::string xmlstring; - XmlWriter writer("",""); + std::ostringstream s; - write(writer, par_.SerialisableClassName(), par_); + s << par(); - return writer.string(); + return s.str(); } template From 85c253ed4ac020ee38d3e103778ec114790138e4 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Wed, 4 Apr 2018 17:19:34 +0100 Subject: [PATCH 027/126] Test_serialisation MPI fix --- tests/IO/Test_serialisation.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/IO/Test_serialisation.cc b/tests/IO/Test_serialisation.cc index bca4d01c..15602e93 100644 --- a/tests/IO/Test_serialisation.cc +++ b/tests/IO/Test_serialisation.cc @@ -120,6 +120,8 @@ void tensorConvTestFn(GridSerialRNG &rng, const std::string label) int main(int argc,char **argv) { + Grid_init(&argc,&argv); + GridSerialRNG rng; rng.SeedFixedIntegers(std::vector({42,10,81,9})); From 9ce00f26f9c76d70b33d7f5090bd984270e15589 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Wed, 4 Apr 2018 17:44:56 +0100 Subject: [PATCH 028/126] not special characters in std::vector operator<< --- lib/serialisation/VectorUtils.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/serialisation/VectorUtils.h b/lib/serialisation/VectorUtils.h index 6df9416d..63aeeb2f 100644 --- a/lib/serialisation/VectorUtils.h +++ b/lib/serialisation/VectorUtils.h @@ -367,13 +367,13 @@ namespace Grid { inline std::ostream & operator<<(std::ostream &os, const std::vector &v) { os << "["; - for (auto &x: v) + for (unsigned int i = 0; i < v.size(); ++i) { - os << x << " "; - } - if (v.size() > 0) - { - os << "\b"; + os << v[i]; + if (i < v.size() - 1) + { + os << " "; + } } os << "]"; From 7dcf5c90e3358589c87f73206f989a3e6b287e34 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 13:16:28 +0100 Subject: [PATCH 029/126] Hadrons: eigenpack must be referred by solver when used --- extras/Hadrons/Modules/MSolver/RBPrecCG.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp index 8d1b0fc6..a47bb67e 100644 --- a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp @@ -107,6 +107,11 @@ std::vector TRBPrecCG::getReference(void) { std::vector ref = {par().action}; + if (!par().eigenPack.empty()) + { + ref.push_back(par().eigenPack); + } + return ref; } From 81050535a567353aeada7fd2f9e683aee5d5248b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 13:48:58 +0100 Subject: [PATCH 030/126] Hadrons: truncate eigenvalues when loading partial eigenpack --- extras/Hadrons/Modules/MIO/LoadEigenPack.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp index bcc3f22b..5d62b53d 100644 --- a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp @@ -112,6 +112,7 @@ void TLoadEigenPack::execute(void) auto &epack = envGetDerived(BasePack, Pack, getName()); epack.read(par().filestem, vm().getTrajectory()); + epack.eval.resize(par().size); } END_MODULE_NAMESPACE From 6b8ffbe73518e4aca665d217bff2e151f50d8e19 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 15:41:31 +0100 Subject: [PATCH 031/126] Hadrons: genetic minimum value type fix --- extras/Hadrons/GeneticScheduler.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/Hadrons/GeneticScheduler.hpp b/extras/Hadrons/GeneticScheduler.hpp index d6f9bdee..e8fcd2c2 100644 --- a/extras/Hadrons/GeneticScheduler.hpp +++ b/extras/Hadrons/GeneticScheduler.hpp @@ -57,7 +57,7 @@ public: virtual ~GeneticScheduler(void) = default; // access const Gene & getMinSchedule(void); - int getMinValue(void); + V getMinValue(void); // breed a new generation void nextGeneration(void); // heuristic benchmarks @@ -116,7 +116,7 @@ GeneticScheduler::getMinSchedule(void) } template -int GeneticScheduler::getMinValue(void) +V GeneticScheduler::getMinValue(void) { return population_.begin()->first; } From eddf023b8a9446fccfbf9bf0648defe35d6969b3 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 16:17:22 +0100 Subject: [PATCH 032/126] pugixml 1.9 update --- lib/pugixml/README.md | 44 - lib/pugixml/pugiconfig.hpp | 11 +- lib/pugixml/pugixml.cc | 3189 ++++++++++++++++++++---------------- lib/pugixml/pugixml.h | 201 ++- lib/pugixml/readme.txt | 6 +- lib/serialisation/XmlIO.cc | 65 +- lib/serialisation/XmlIO.h | 9 +- 7 files changed, 1935 insertions(+), 1590 deletions(-) delete mode 100644 lib/pugixml/README.md diff --git a/lib/pugixml/README.md b/lib/pugixml/README.md deleted file mode 100644 index 9d8a935f..00000000 --- a/lib/pugixml/README.md +++ /dev/null @@ -1,44 +0,0 @@ -pugixml [![Build Status](https://travis-ci.org/zeux/pugixml.svg?branch=master)](https://travis-ci.org/zeux/pugixml) [![Build status](https://ci.appveyor.com/api/projects/status/9hdks1doqvq8pwe7/branch/master?svg=true)](https://ci.appveyor.com/project/zeux/pugixml) -======= - -pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification -capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 -implementation for complex data-driven tree queries. Full Unicode support is also available, with Unicode interface -variants and conversions between different Unicode encodings (which happen automatically during parsing/saving). - -pugixml is used by a lot of projects, both open-source and proprietary, for performance and easy-to-use interface. - -## Documentation - -Documentation for the current release of pugixml is available on-line as two separate documents: - -* [Quick-start guide](http://pugixml.org/docs/quickstart.html), that aims to provide enough information to start using the library; -* [Complete reference manual](http://pugixml.org/docs/manual.html), that describes all features of the library in detail. - -You’re advised to start with the quick-start guide; however, many important library features are either not described in it at all or only mentioned briefly; if you require more information you should read the complete manual. - -## License -This library is available to anybody free of charge, under the terms of MIT License: - -Copyright (c) 2006-2015 Arseny Kapoulkine - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/pugixml/pugiconfig.hpp b/lib/pugixml/pugiconfig.hpp index 5ee5131f..f739e062 100644 --- a/lib/pugixml/pugiconfig.hpp +++ b/lib/pugixml/pugiconfig.hpp @@ -1,7 +1,7 @@ /** - * pugixml parser - version 1.6 + * pugixml parser - version 1.9 * -------------------------------------------------------- - * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end @@ -17,6 +17,9 @@ // Uncomment this to enable wchar_t mode // #define PUGIXML_WCHAR_MODE +// Uncomment this to enable compact mode +// #define PUGIXML_COMPACT + // Uncomment this to disable XPath // #define PUGIXML_NO_XPATH @@ -46,7 +49,7 @@ #endif /** - * Copyright (c) 2006-2015 Arseny Kapoulkine + * Copyright (c) 2006-2018 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -59,7 +62,7 @@ * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND diff --git a/lib/pugixml/pugixml.cc b/lib/pugixml/pugixml.cc index a4f8fde2..dd08092c 100644 --- a/lib/pugixml/pugixml.cc +++ b/lib/pugixml/pugixml.cc @@ -1,7 +1,7 @@ /** - * pugixml parser - version 1.6 + * pugixml parser - version 1.9 * -------------------------------------------------------- - * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef PUGIXML_WCHAR_MODE # include @@ -28,9 +29,6 @@ #ifndef PUGIXML_NO_XPATH # include # include -# ifdef PUGIXML_NO_EXCEPTIONS -# include -# endif #endif #ifndef PUGIXML_NO_STL @@ -46,14 +44,17 @@ # pragma warning(push) # pragma warning(disable: 4127) // conditional expression is constant # pragma warning(disable: 4324) // structure was padded due to __declspec(align()) -# pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable # pragma warning(disable: 4702) // unreachable code # pragma warning(disable: 4996) // this function or variable may be unsafe -# pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged +#endif + +#if defined(_MSC_VER) && defined(__c2__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated" // this function or variable may be unsafe #endif #ifdef __INTEL_COMPILER -# pragma warning(disable: 177) // function was declared but never referenced +# pragma warning(disable: 177) // function was declared but never referenced # pragma warning(disable: 279) // controlling expression is constant # pragma warning(disable: 1478 1786) // function was declared "deprecated" # pragma warning(disable: 1684) // conversion from pointer to same-sized integral type @@ -75,17 +76,21 @@ # pragma diag_suppress=237 // controlling expression is constant #endif +#ifdef __TI_COMPILER_VERSION__ +# pragma diag_suppress 179 // function was declared but never referenced +#endif + // Inlining controls #if defined(_MSC_VER) && _MSC_VER >= 1300 # define PUGI__NO_INLINE __declspec(noinline) #elif defined(__GNUC__) # define PUGI__NO_INLINE __attribute__((noinline)) #else -# define PUGI__NO_INLINE +# define PUGI__NO_INLINE #endif // Branch weight controls -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__c2__) # define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0) #else # define PUGI__UNLIKELY(cond) (cond) @@ -101,10 +106,29 @@ # define PUGI__DMC_VOLATILE #endif +// Integer sanitizer workaround; we only apply this for clang since gcc8 has no_sanitize but not unsigned-integer-overflow and produces "attribute directive ignored" warnings +#if defined(__clang__) && defined(__has_attribute) +# if __has_attribute(no_sanitize) +# define PUGI__UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) +# else +# define PUGI__UNSIGNED_OVERFLOW +# endif +#else +# define PUGI__UNSIGNED_OVERFLOW +#endif + // Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all) #if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) using std::memcpy; using std::memmove; +using std::memset; +#endif + +// Some MinGW/GCC versions have headers that erroneously omit LLONG_MIN/LLONG_MAX/ULLONG_MAX definitions from limits.h in some configurations +#if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX) +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define LLONG_MAX __LONG_LONG_MAX__ +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) #endif // In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features @@ -112,6 +136,16 @@ using std::memmove; # define PUGI__MSVC_CRT_VERSION _MSC_VER #endif +// Not all platforms have snprintf; we define a wrapper that uses snprintf if possible. This only works with buffers with a known size. +#if __cplusplus >= 201103 +# define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) +#elif defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 +# define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__) +#else +# define PUGI__SNPRINTF sprintf +#endif + +// We put implementation details into an anonymous namespace in source mode, but have to keep it in non-anonymous namespace in header-only mode to prevent binary bloat. #ifdef PUGIXML_HEADER_ONLY # define PUGI__NS_BEGIN namespace pugi { namespace impl { # define PUGI__NS_END } } @@ -130,9 +164,7 @@ using std::memmove; #endif // uintptr_t -#if !defined(_MSC_VER) || _MSC_VER >= 1600 -# include -#else +#if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561) namespace pugi { # ifndef _UINTPTR_T_DEFINED @@ -143,6 +175,8 @@ namespace pugi typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; } +#else +# include #endif // Memory allocation @@ -204,7 +238,7 @@ PUGI__NS_BEGIN for (size_t i = 0; i < count; ++i) if (lhs[i] != rhs[i]) return false; - + return lhs[count] == 0; } @@ -221,21 +255,14 @@ PUGI__NS_BEGIN return static_cast(end - s); #endif } - -#ifdef PUGIXML_WCHAR_MODE - // Convert string to wide string, assuming all symbols are ASCII - PUGI__FN void widen_ascii(wchar_t* dest, const char* source) - { - for (const char* i = source; *i; ++i) *dest++ = *i; - *dest = 0; - } -#endif PUGI__NS_END // auto_ptr-like object for exception recovery PUGI__NS_BEGIN - template struct auto_deleter + template struct auto_deleter { + typedef void (*D)(T*); + T* data; D deleter; @@ -277,67 +304,37 @@ PUGI__NS_BEGIN } } - void** find(const void* key) + void* find(const void* key) { - assert(key); - if (_capacity == 0) return 0; - size_t hashmod = _capacity - 1; - size_t bucket = hash(key) & hashmod; + item_t* item = get_item(key); + assert(item); + assert(item->key == key || (item->key == 0 && item->value == 0)); - for (size_t probe = 0; probe <= hashmod; ++probe) - { - item_t& probe_item = _items[bucket]; - - if (probe_item.key == key) - return &probe_item.value; - - if (probe_item.key == 0) - return 0; - - // hash collision, quadratic probing - bucket = (bucket + probe + 1) & hashmod; - } - - assert(!"Hash table is full"); - return 0; + return item->value; } - void** insert(const void* key) + void insert(const void* key, void* value) { - assert(key); - assert(_count < _capacity * 3 / 4); + assert(_capacity != 0 && _count < _capacity - _capacity / 4); - size_t hashmod = _capacity - 1; - size_t bucket = hash(key) & hashmod; + item_t* item = get_item(key); + assert(item); - for (size_t probe = 0; probe <= hashmod; ++probe) + if (item->key == 0) { - item_t& probe_item = _items[bucket]; - - if (probe_item.key == 0) - { - probe_item.key = key; - _count++; - return &probe_item.value; - } - - if (probe_item.key == key) - return &probe_item.value; - - // hash collision, quadratic probing - bucket = (bucket + probe + 1) & hashmod; + _count++; + item->key = key; } - assert(!"Hash table is full"); - return 0; + item->value = value; } - bool reserve() + bool reserve(size_t extra = 16) { - if (_count + 16 >= _capacity - _capacity / 4) - return rehash(); + if (_count + extra >= _capacity - _capacity / 4) + return rehash(_count + extra); return true; } @@ -354,9 +351,32 @@ PUGI__NS_BEGIN size_t _count; - bool rehash(); + bool rehash(size_t count); - static unsigned int hash(const void* key) + item_t* get_item(const void* key) + { + assert(key); + assert(_capacity > 0); + + size_t hashmod = _capacity - 1; + size_t bucket = hash(key) & hashmod; + + for (size_t probe = 0; probe <= hashmod; ++probe) + { + item_t& probe_item = _items[bucket]; + + if (probe_item.key == key || probe_item.key == 0) + return &probe_item; + + // hash collision, quadratic probing + bucket = (bucket + probe + 1) & hashmod; + } + + assert(false && "Hash table is full"); // unreachable + return 0; + } + + static PUGI__UNSIGNED_OVERFLOW unsigned int hash(const void* key) { unsigned int h = static_cast(reinterpret_cast(key)); @@ -371,27 +391,33 @@ PUGI__NS_BEGIN } }; - PUGI__FN_NO_INLINE bool compact_hash_table::rehash() + PUGI__FN_NO_INLINE bool compact_hash_table::rehash(size_t count) { + size_t capacity = 32; + while (count >= capacity - capacity / 4) + capacity *= 2; + compact_hash_table rt; - rt._capacity = (_capacity == 0) ? 32 : _capacity * 2; - rt._items = static_cast(xml_memory::allocate(sizeof(item_t) * rt._capacity)); + rt._capacity = capacity; + rt._items = static_cast(xml_memory::allocate(sizeof(item_t) * capacity)); if (!rt._items) return false; - memset(rt._items, 0, sizeof(item_t) * rt._capacity); + memset(rt._items, 0, sizeof(item_t) * capacity); for (size_t i = 0; i < _capacity; ++i) if (_items[i].key) - *rt.insert(_items[i].key) = _items[i].value; + rt.insert(_items[i].key, _items[i].value); if (_items) xml_memory::deallocate(_items); - _capacity = rt._capacity; + _capacity = capacity; _items = rt._items; + assert(_count == rt._count); + return true; } @@ -399,43 +425,33 @@ PUGI__NS_END #endif PUGI__NS_BEGIN - static const size_t xml_memory_page_size = - #ifdef PUGIXML_MEMORY_PAGE_SIZE - PUGIXML_MEMORY_PAGE_SIZE - #else - 32768 - #endif - ; - #ifdef PUGIXML_COMPACT static const uintptr_t xml_memory_block_alignment = 4; - - static const uintptr_t xml_memory_page_alignment = sizeof(void*); #else static const uintptr_t xml_memory_block_alignment = sizeof(void*); - - static const uintptr_t xml_memory_page_alignment = 64; - static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1); #endif // extra metadata bits - static const uintptr_t xml_memory_page_contents_shared_mask = 32; - static const uintptr_t xml_memory_page_name_allocated_mask = 16; - static const uintptr_t xml_memory_page_value_allocated_mask = 8; - static const uintptr_t xml_memory_page_type_mask = 7; + static const uintptr_t xml_memory_page_contents_shared_mask = 64; + static const uintptr_t xml_memory_page_name_allocated_mask = 32; + static const uintptr_t xml_memory_page_value_allocated_mask = 16; + static const uintptr_t xml_memory_page_type_mask = 15; // combined masks for string uniqueness static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask; static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask; #ifdef PUGIXML_COMPACT + #define PUGI__GETHEADER_IMPL(object, page, flags) // unused #define PUGI__GETPAGE_IMPL(header) (header).get_page() #else - #define PUGI__GETPAGE_IMPL(header) reinterpret_cast((header) & impl::xml_memory_page_pointer_mask) + #define PUGI__GETHEADER_IMPL(object, page, flags) (((reinterpret_cast(object) - reinterpret_cast(page)) << 8) | (flags)) + // this macro casts pointers through void* to avoid 'cast increases required alignment of target type' warnings + #define PUGI__GETPAGE_IMPL(header) static_cast(const_cast(static_cast(reinterpret_cast(&header) - (header >> 8)))) #endif #define PUGI__GETPAGE(n) PUGI__GETPAGE_IMPL((n)->header) - #define PUGI__NODETYPE(n) static_cast(((n)->header & impl::xml_memory_page_type_mask) + 1) + #define PUGI__NODETYPE(n) static_cast((n)->header & impl::xml_memory_page_type_mask) struct xml_allocator; @@ -475,6 +491,14 @@ PUGI__NS_BEGIN #endif }; + static const size_t xml_memory_page_size = + #ifdef PUGIXML_MEMORY_PAGE_SIZE + (PUGIXML_MEMORY_PAGE_SIZE) + #else + 32768 + #endif + - sizeof(xml_memory_page); + struct xml_memory_string_header { uint16_t page_offset; // offset from page->data @@ -495,30 +519,21 @@ PUGI__NS_BEGIN size_t size = sizeof(xml_memory_page) + data_size; // allocate block with some alignment, leaving memory for worst-case padding - void* memory = xml_memory::allocate(size + xml_memory_page_alignment); + void* memory = xml_memory::allocate(size); if (!memory) return 0; - // align to next page boundary (note: this guarantees at least 1 usable byte before the page) - char* page_memory = reinterpret_cast((reinterpret_cast(memory) + xml_memory_page_alignment) & ~(xml_memory_page_alignment - 1)); - // prepare page structure - xml_memory_page* page = xml_memory_page::construct(page_memory); + xml_memory_page* page = xml_memory_page::construct(memory); assert(page); page->allocator = _root->allocator; - // record the offset for freeing the memory block - assert(page_memory > memory && page_memory - static_cast(memory) <= 127); - page_memory[-1] = static_cast(page_memory - static_cast(memory)); - return page; } static void deallocate_page(xml_memory_page* page) { - char* page_memory = reinterpret_cast(page); - - xml_memory::deallocate(page_memory - page_memory[-1]); + xml_memory::deallocate(page); } void* allocate_memory_oob(size_t size, xml_memory_page*& out_page); @@ -627,7 +642,7 @@ PUGI__NS_BEGIN // allocate memory for string and header block size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); - + // round size up to block alignment boundary size_t full_size = (size + (xml_memory_block_alignment - 1)) & ~(xml_memory_block_alignment - 1); @@ -749,12 +764,12 @@ PUGI__NS_BEGIN void operator&=(uintptr_t mod) { - _flags &= mod; + _flags &= static_cast(mod); } void operator|=(uintptr_t mod) { - _flags |= mod; + _flags |= static_cast(mod); } uintptr_t operator&(uintptr_t mod) const @@ -764,10 +779,11 @@ PUGI__NS_BEGIN xml_memory_page* get_page() const { + // round-trip through void* to silence 'cast increases required alignment of target type' warnings const char* page_marker = reinterpret_cast(this) - (_page << compact_alignment_log2); - const char* page = page_marker - *reinterpret_cast(page_marker); + const char* page = page_marker - *reinterpret_cast(static_cast(page_marker)); - return const_cast(reinterpret_cast(page)); + return const_cast(reinterpret_cast(static_cast(page))); } private: @@ -784,12 +800,12 @@ PUGI__NS_BEGIN template PUGI__FN_NO_INLINE T* compact_get_value(const void* object) { - return static_cast(*compact_get_page(object, header_offset)->allocator->_hash->find(object)); + return static_cast(compact_get_page(object, header_offset)->allocator->_hash->find(object)); } template PUGI__FN_NO_INLINE void compact_set_value(const void* object, T* value) { - *compact_get_page(object, header_offset)->allocator->_hash->insert(object) = value; + compact_get_page(object, header_offset)->allocator->_hash->insert(object, value); } template class compact_pointer @@ -836,7 +852,7 @@ PUGI__NS_BEGIN { uintptr_t base = reinterpret_cast(this) & ~(compact_alignment - 1); - return reinterpret_cast(base + ((_data - 1 + start) << compact_alignment_log2)); + return reinterpret_cast(base + (_data - 1 + start) * compact_alignment); } else return compact_get_value(this); @@ -847,7 +863,7 @@ PUGI__NS_BEGIN T* operator->() const { - return operator T*(); + return *this; } private: @@ -914,7 +930,7 @@ PUGI__NS_BEGIN { uintptr_t base = reinterpret_cast(this) & ~(compact_alignment - 1); - return reinterpret_cast(base + ((_data - 1 - 65533) << compact_alignment_log2)); + return reinterpret_cast(base + (_data - 1 - 65533) * compact_alignment); } else if (_data == 65534) return static_cast(compact_get_page(this, header_offset)->compact_shared_parent); @@ -927,7 +943,7 @@ PUGI__NS_BEGIN T* operator->() const { - return operator T*(); + return *this; } private: @@ -959,7 +975,8 @@ PUGI__NS_BEGIN if (static_cast(offset) < (65535 << 7)) { - uint16_t* base = reinterpret_cast(reinterpret_cast(this) - base_offset); + // round-trip through void* to silence 'cast increases required alignment of target type' warnings + uint16_t* base = reinterpret_cast(static_cast(reinterpret_cast(this) - base_offset)); if (*base == 0) { @@ -1003,7 +1020,8 @@ PUGI__NS_BEGIN { xml_memory_page* page = compact_get_page(this, header_offset); - const uint16_t* base = reinterpret_cast(reinterpret_cast(this) - base_offset); + // round-trip through void* to silence 'cast increases required alignment of target type' warnings + const uint16_t* base = reinterpret_cast(static_cast(reinterpret_cast(this) - base_offset)); assert(*base); ptrdiff_t offset = ((*base - 1) << 7) + (_data - 1); @@ -1048,7 +1066,7 @@ namespace pugi struct xml_node_struct { - xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(page, type - 1), namevalue_base(0) + xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(page, type), namevalue_base(0) { PUGI__STATIC_ASSERT(sizeof(xml_node_struct) == 12); } @@ -1075,8 +1093,9 @@ namespace pugi { struct xml_attribute_struct { - xml_attribute_struct(impl::xml_memory_page* page): header(reinterpret_cast(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0) + xml_attribute_struct(impl::xml_memory_page* page): name(0), value(0), prev_attribute_c(0), next_attribute(0) { + header = PUGI__GETHEADER_IMPL(this, page, 0); } uintptr_t header; @@ -1090,8 +1109,9 @@ namespace pugi struct xml_node_struct { - xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(reinterpret_cast(page) | (type - 1)), name(0), value(0), parent(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) + xml_node_struct(impl::xml_memory_page* page, xml_node_type type): name(0), value(0), parent(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) { + header = PUGI__GETHEADER_IMPL(this, page, type); } uintptr_t header; @@ -1122,9 +1142,6 @@ PUGI__NS_BEGIN { xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0), extra_buffers(0) { - #ifdef PUGIXML_COMPACT - _hash = &hash; - #endif } const char_t* buffer; @@ -1599,28 +1616,11 @@ PUGI__NS_BEGIN } }; - template struct wchar_selector; - - template <> struct wchar_selector<2> + struct utf8_decoder { - typedef uint16_t type; - typedef utf16_counter counter; - typedef utf16_writer writer; - }; + typedef uint8_t type; - template <> struct wchar_selector<4> - { - typedef uint32_t type; - typedef utf32_counter counter; - typedef utf32_writer writer; - }; - - typedef wchar_selector::counter wchar_counter; - typedef wchar_selector::writer wchar_writer; - - template struct utf_decoder - { - static inline typename Traits::value_type decode_utf8_block(const uint8_t* data, size_t size, typename Traits::value_type result) + template static inline typename Traits::value_type process(const uint8_t* data, size_t size, typename Traits::value_type result, Traits) { const uint8_t utf8_byte_mask = 0x3f; @@ -1681,29 +1681,34 @@ PUGI__NS_BEGIN return result; } + }; - static inline typename Traits::value_type decode_utf16_block(const uint16_t* data, size_t size, typename Traits::value_type result) + template struct utf16_decoder + { + typedef uint16_t type; + + template static inline typename Traits::value_type process(const uint16_t* data, size_t size, typename Traits::value_type result, Traits) { - const uint16_t* end = data + size; - - while (data < end) + while (size) { - unsigned int lead = opt_swap::value ? endian_swap(*data) : *data; + uint16_t lead = opt_swap::value ? endian_swap(*data) : *data; // U+0000..U+D7FF if (lead < 0xD800) { result = Traits::low(result, lead); data += 1; + size -= 1; } // U+E000..U+FFFF else if (static_cast(lead - 0xE000) < 0x2000) { result = Traits::low(result, lead); data += 1; + size -= 1; } // surrogate pair lead - else if (static_cast(lead - 0xD800) < 0x400 && data + 1 < end) + else if (static_cast(lead - 0xD800) < 0x400 && size >= 2) { uint16_t next = opt_swap::value ? endian_swap(data[1]) : data[1]; @@ -1711,26 +1716,32 @@ PUGI__NS_BEGIN { result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff)); data += 2; + size -= 2; } else { data += 1; + size -= 1; } } else { data += 1; + size -= 1; } } return result; } + }; - static inline typename Traits::value_type decode_utf32_block(const uint32_t* data, size_t size, typename Traits::value_type result) + template struct utf32_decoder + { + typedef uint32_t type; + + template static inline typename Traits::value_type process(const uint32_t* data, size_t size, typename Traits::value_type result, Traits) { - const uint32_t* end = data + size; - - while (data < end) + while (size) { uint32_t lead = opt_swap::value ? endian_swap(*data) : *data; @@ -1739,53 +1750,76 @@ PUGI__NS_BEGIN { result = Traits::low(result, lead); data += 1; + size -= 1; } // U+10000..U+10FFFF else { result = Traits::high(result, lead); data += 1; + size -= 1; } } return result; } + }; - static inline typename Traits::value_type decode_latin1_block(const uint8_t* data, size_t size, typename Traits::value_type result) + struct latin1_decoder + { + typedef uint8_t type; + + template static inline typename Traits::value_type process(const uint8_t* data, size_t size, typename Traits::value_type result, Traits) { - for (size_t i = 0; i < size; ++i) + while (size) { - result = Traits::low(result, data[i]); + result = Traits::low(result, *data); + data += 1; + size -= 1; } return result; } - - static inline typename Traits::value_type decode_wchar_block_impl(const uint16_t* data, size_t size, typename Traits::value_type result) - { - return decode_utf16_block(data, size, result); - } - - static inline typename Traits::value_type decode_wchar_block_impl(const uint32_t* data, size_t size, typename Traits::value_type result) - { - return decode_utf32_block(data, size, result); - } - - static inline typename Traits::value_type decode_wchar_block(const wchar_t* data, size_t size, typename Traits::value_type result) - { - return decode_wchar_block_impl(reinterpret_cast::type*>(data), size, result); - } }; - template PUGI__FN void convert_utf_endian_swap(T* result, const T* data, size_t length) + template struct wchar_selector; + + template <> struct wchar_selector<2> { - for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]); - } + typedef uint16_t type; + typedef utf16_counter counter; + typedef utf16_writer writer; + typedef utf16_decoder decoder; + }; + + template <> struct wchar_selector<4> + { + typedef uint32_t type; + typedef utf32_counter counter; + typedef utf32_writer writer; + typedef utf32_decoder decoder; + }; + + typedef wchar_selector::counter wchar_counter; + typedef wchar_selector::writer wchar_writer; + + struct wchar_decoder + { + typedef wchar_t type; + + template static inline typename Traits::value_type process(const wchar_t* data, size_t size, typename Traits::value_type result, Traits traits) + { + typedef wchar_selector::decoder decoder; + + return decoder::process(reinterpret_cast(data), size, result, traits); + } + }; #ifdef PUGIXML_WCHAR_MODE PUGI__FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) { - for (size_t i = 0; i < length; ++i) result[i] = static_cast(endian_swap(static_cast::type>(data[i]))); + for (size_t i = 0; i < length; ++i) + result[i] = static_cast(endian_swap(static_cast::type>(data[i]))); } #endif PUGI__NS_END @@ -1832,7 +1866,7 @@ PUGI__NS_BEGIN ctx_digit = 8, // 0-9 ctx_symbol = 16 // Any symbol > 127, a-z, A-Z, 0-9, _, -, . }; - + static const unsigned char chartypex_table[256] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3, // 0-15 @@ -1854,7 +1888,7 @@ PUGI__NS_BEGIN 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }; - + #ifdef PUGIXML_WCHAR_MODE #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast(c) < 128 ? table[static_cast(c)] : table[128]) & (ct)) #else @@ -1877,12 +1911,71 @@ PUGI__NS_BEGIN if (sizeof(wchar_t) == 2) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - else + else return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; } - PUGI__FN xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) + PUGI__FN bool parse_declaration_encoding(const uint8_t* data, size_t size, const uint8_t*& out_encoding, size_t& out_length) { + #define PUGI__SCANCHAR(ch) { if (offset >= size || data[offset] != ch) return false; offset++; } + #define PUGI__SCANCHARTYPE(ct) { while (offset < size && PUGI__IS_CHARTYPE(data[offset], ct)) offset++; } + + // check if we have a non-empty XML declaration + if (size < 6 || !((data[0] == '<') & (data[1] == '?') & (data[2] == 'x') & (data[3] == 'm') & (data[4] == 'l') && PUGI__IS_CHARTYPE(data[5], ct_space))) + return false; + + // scan XML declaration until the encoding field + for (size_t i = 6; i + 1 < size; ++i) + { + // declaration can not contain ? in quoted values + if (data[i] == '?') + return false; + + if (data[i] == 'e' && data[i + 1] == 'n') + { + size_t offset = i; + + // encoding follows the version field which can't contain 'en' so this has to be the encoding if XML is well formed + PUGI__SCANCHAR('e'); PUGI__SCANCHAR('n'); PUGI__SCANCHAR('c'); PUGI__SCANCHAR('o'); + PUGI__SCANCHAR('d'); PUGI__SCANCHAR('i'); PUGI__SCANCHAR('n'); PUGI__SCANCHAR('g'); + + // S? = S? + PUGI__SCANCHARTYPE(ct_space); + PUGI__SCANCHAR('='); + PUGI__SCANCHARTYPE(ct_space); + + // the only two valid delimiters are ' and " + uint8_t delimiter = (offset < size && data[offset] == '"') ? '"' : '\''; + + PUGI__SCANCHAR(delimiter); + + size_t start = offset; + + out_encoding = data + offset; + + PUGI__SCANCHARTYPE(ct_symbol); + + out_length = offset - start; + + PUGI__SCANCHAR(delimiter); + + return true; + } + } + + return false; + + #undef PUGI__SCANCHAR + #undef PUGI__SCANCHARTYPE + } + + PUGI__FN xml_encoding guess_buffer_encoding(const uint8_t* data, size_t size) + { + // skip encoding autodetection if input buffer is too small + if (size < 4) return encoding_utf8; + + uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; + // look for BOM in first few bytes if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff) return encoding_utf32_be; if (d0 == 0xff && d1 == 0xfe && d2 == 0 && d3 == 0) return encoding_utf32_le; @@ -1895,13 +1988,32 @@ PUGI__NS_BEGIN if (d0 == 0x3c && d1 == 0 && d2 == 0 && d3 == 0) return encoding_utf32_le; if (d0 == 0 && d1 == 0x3c && d2 == 0 && d3 == 0x3f) return encoding_utf16_be; if (d0 == 0x3c && d1 == 0 && d2 == 0x3f && d3 == 0) return encoding_utf16_le; - if (d0 == 0x3c && d1 == 0x3f && d2 == 0x78 && d3 == 0x6d) return encoding_utf8; // look for utf16 < followed by node name (this may fail, but is better than utf8 since it's zero terminated so early) if (d0 == 0 && d1 == 0x3c) return encoding_utf16_be; if (d0 == 0x3c && d1 == 0) return encoding_utf16_le; - // no known BOM detected, assume utf8 + // no known BOM detected; parse declaration + const uint8_t* enc = 0; + size_t enc_length = 0; + + if (d0 == 0x3c && d1 == 0x3f && d2 == 0x78 && d3 == 0x6d && parse_declaration_encoding(data, size, enc, enc_length)) + { + // iso-8859-1 (case-insensitive) + if (enc_length == 10 + && (enc[0] | ' ') == 'i' && (enc[1] | ' ') == 's' && (enc[2] | ' ') == 'o' + && enc[3] == '-' && enc[4] == '8' && enc[5] == '8' && enc[6] == '5' && enc[7] == '9' + && enc[8] == '-' && enc[9] == '1') + return encoding_latin1; + + // latin1 (case-insensitive) + if (enc_length == 6 + && (enc[0] | ' ') == 'l' && (enc[1] | ' ') == 'a' && (enc[2] | ' ') == 't' + && (enc[3] | ' ') == 'i' && (enc[4] | ' ') == 'n' + && enc[5] == '1') + return encoding_latin1; + } + return encoding_utf8; } @@ -1919,15 +2031,10 @@ PUGI__NS_BEGIN // only do autodetection if no explicit encoding is requested if (encoding != encoding_auto) return encoding; - // skip encoding autodetection if input buffer is too small - if (size < 4) return encoding_utf8; - // try to guess encoding (based on XML specification, Appendix F.1) const uint8_t* data = static_cast(contents); - PUGI__DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; - - return guess_buffer_encoding(d0, d1, d2, d3); + return guess_buffer_encoding(data, size); } PUGI__FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) @@ -1994,38 +2101,13 @@ PUGI__NS_BEGIN return true; } - PUGI__FN bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) + template PUGI__FN bool convert_buffer_generic(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, D) { - const uint8_t* data = static_cast(contents); - size_t data_length = size; + const typename D::type* data = static_cast(contents); + size_t data_length = size / sizeof(typename D::type); // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf8_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf8 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_utf8_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint16_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint16_t); - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf16_block(data, data_length, 0); + size_t length = D::process(data, data_length, 0, wchar_counter()); // allocate buffer of suitable length char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); @@ -2033,57 +2115,7 @@ PUGI__NS_BEGIN // second pass: convert utf16 input to wchar_t wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_utf16_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint32_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint32_t); - - // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf32_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf32 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_utf32_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size) - { - const uint8_t* data = static_cast(contents); - size_t data_length = size; - - // get length in wchar_t units - size_t length = data_length; - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // convert latin1 input to wchar_t - wchar_writer::value_type obegin = reinterpret_cast(buffer); - wchar_writer::value_type oend = utf_decoder::decode_latin1_block(data, data_length, obegin); + wchar_writer::value_type oend = D::process(data, data_length, obegin, wchar_writer()); assert(oend == obegin + length); *oend = 0; @@ -2100,13 +2132,16 @@ PUGI__NS_BEGIN xml_encoding wchar_encoding = get_wchar_encoding(); // fast path: no conversion required - if (encoding == wchar_encoding) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); + if (encoding == wchar_encoding) + return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); // only endian-swapping is required - if (need_endian_swap_utf(encoding, wchar_encoding)) return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable); + if (need_endian_swap_utf(encoding, wchar_encoding)) + return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable); // source encoding is utf8 - if (encoding == encoding_utf8) return convert_buffer_utf8(out_buffer, out_length, contents, size); + if (encoding == encoding_utf8) + return convert_buffer_generic(out_buffer, out_length, contents, size, utf8_decoder()); // source encoding is utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) @@ -2114,8 +2149,8 @@ PUGI__NS_BEGIN xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; return (native_encoding == encoding) ? - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); + convert_buffer_generic(out_buffer, out_length, contents, size, utf16_decoder()) : + convert_buffer_generic(out_buffer, out_length, contents, size, utf16_decoder()); } // source encoding is utf32 @@ -2124,24 +2159,25 @@ PUGI__NS_BEGIN xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; return (native_encoding == encoding) ? - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); + convert_buffer_generic(out_buffer, out_length, contents, size, utf32_decoder()) : + convert_buffer_generic(out_buffer, out_length, contents, size, utf32_decoder()); } // source encoding is latin1 - if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size); + if (encoding == encoding_latin1) + return convert_buffer_generic(out_buffer, out_length, contents, size, latin1_decoder()); - assert(!"Invalid encoding"); + assert(false && "Invalid encoding"); // unreachable return false; } #else - template PUGI__FN bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) + template PUGI__FN bool convert_buffer_generic(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, D) { - const uint16_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint16_t); + const typename D::type* data = static_cast(contents); + size_t data_length = size / sizeof(typename D::type); // first pass: get length in utf8 units - size_t length = utf_decoder::decode_utf16_block(data, data_length, 0); + size_t length = D::process(data, data_length, 0, utf8_counter()); // allocate buffer of suitable length char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); @@ -2149,32 +2185,7 @@ PUGI__NS_BEGIN // second pass: convert utf16 input to utf8 uint8_t* obegin = reinterpret_cast(buffer); - uint8_t* oend = utf_decoder::decode_utf16_block(data, data_length, obegin); - - assert(oend == obegin + length); - *oend = 0; - - out_buffer = buffer; - out_length = length + 1; - - return true; - } - - template PUGI__FN bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap) - { - const uint32_t* data = static_cast(contents); - size_t data_length = size / sizeof(uint32_t); - - // first pass: get length in utf8 units - size_t length = utf_decoder::decode_utf32_block(data, data_length, 0); - - // allocate buffer of suitable length - char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); - if (!buffer) return false; - - // second pass: convert utf32 input to utf8 - uint8_t* obegin = reinterpret_cast(buffer); - uint8_t* oend = utf_decoder::decode_utf32_block(data, data_length, obegin); + uint8_t* oend = D::process(data, data_length, obegin, utf8_writer()); assert(oend == obegin + length); *oend = 0; @@ -2210,7 +2221,7 @@ PUGI__NS_BEGIN if (postfix_length == 0) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); // first pass: get length in utf8 units - size_t length = prefix_length + utf_decoder::decode_latin1_block(postfix, postfix_length, 0); + size_t length = prefix_length + latin1_decoder::process(postfix, postfix_length, 0, utf8_counter()); // allocate buffer of suitable length char_t* buffer = static_cast(xml_memory::allocate((length + 1) * sizeof(char_t))); @@ -2220,7 +2231,7 @@ PUGI__NS_BEGIN memcpy(buffer, data, prefix_length); uint8_t* obegin = reinterpret_cast(buffer); - uint8_t* oend = utf_decoder::decode_latin1_block(postfix, postfix_length, obegin + prefix_length); + uint8_t* oend = latin1_decoder::process(postfix, postfix_length, obegin + prefix_length, utf8_writer()); assert(oend == obegin + length); *oend = 0; @@ -2234,7 +2245,8 @@ PUGI__NS_BEGIN PUGI__FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable) { // fast path: no conversion required - if (encoding == encoding_utf8) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); + if (encoding == encoding_utf8) + return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); // source encoding is utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) @@ -2242,8 +2254,8 @@ PUGI__NS_BEGIN xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; return (native_encoding == encoding) ? - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true()); + convert_buffer_generic(out_buffer, out_length, contents, size, utf16_decoder()) : + convert_buffer_generic(out_buffer, out_length, contents, size, utf16_decoder()); } // source encoding is utf32 @@ -2252,14 +2264,15 @@ PUGI__NS_BEGIN xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; return (native_encoding == encoding) ? - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) : - convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true()); + convert_buffer_generic(out_buffer, out_length, contents, size, utf32_decoder()) : + convert_buffer_generic(out_buffer, out_length, contents, size, utf32_decoder()); } // source encoding is latin1 - if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); + if (encoding == encoding_latin1) + return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable); - assert(!"Invalid encoding"); + assert(false && "Invalid encoding"); // unreachable return false; } #endif @@ -2267,20 +2280,20 @@ PUGI__NS_BEGIN PUGI__FN size_t as_utf8_begin(const wchar_t* str, size_t length) { // get length in utf8 characters - return utf_decoder::decode_wchar_block(str, length, 0); + return wchar_decoder::process(str, length, 0, utf8_counter()); } PUGI__FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) { // convert to utf8 uint8_t* begin = reinterpret_cast(buffer); - uint8_t* end = utf_decoder::decode_wchar_block(str, length, begin); - + uint8_t* end = wchar_decoder::process(str, length, begin, utf8_writer()); + assert(begin + size == end); (void)!end; (void)!size; } - + #ifndef PUGIXML_NO_STL PUGI__FN std::string as_utf8_impl(const wchar_t* str, size_t length) { @@ -2302,7 +2315,7 @@ PUGI__NS_BEGIN const uint8_t* data = reinterpret_cast(str); // first pass: get length in wchar_t units - size_t length = utf_decoder::decode_utf8_block(data, size, 0); + size_t length = utf8_decoder::process(data, size, 0, wchar_counter()); // allocate resulting string std::basic_string result; @@ -2312,7 +2325,7 @@ PUGI__NS_BEGIN if (length > 0) { wchar_writer::value_type begin = reinterpret_cast(&result[0]); - wchar_writer::value_type end = utf_decoder::decode_utf8_block(data, size, begin); + wchar_writer::value_type end = utf8_decoder::process(data, size, begin, wchar_writer()); assert(begin + length == end); (void)!end; @@ -2340,17 +2353,15 @@ PUGI__NS_BEGIN } template - PUGI__FN bool strcpy_insitu(String& dest, Header& header, uintptr_t header_mask, const char_t* source) + PUGI__FN bool strcpy_insitu(String& dest, Header& header, uintptr_t header_mask, const char_t* source, size_t source_length) { - size_t source_length = strlength(source); - if (source_length == 0) { // empty string and null pointer are equivalent, so just deallocate old memory xml_allocator* alloc = PUGI__GETPAGE_IMPL(header)->allocator; if (header & header_mask) alloc->deallocate_string(dest); - + // mark the string as not allocated dest = 0; header &= ~header_mask; @@ -2360,8 +2371,9 @@ PUGI__NS_BEGIN else if (dest && strcpy_insitu_allow(source_length, header, header_mask, dest)) { // we can reuse old buffer, so just copy the new data (including zero terminator) - memcpy(dest, source, (source_length + 1) * sizeof(char_t)); - + memcpy(dest, source, source_length * sizeof(char_t)); + dest[source_length] = 0; + return true; } else @@ -2375,11 +2387,12 @@ PUGI__NS_BEGIN if (!buf) return false; // copy the string (including zero terminator) - memcpy(buf, source, (source_length + 1) * sizeof(char_t)); + memcpy(buf, source, source_length * sizeof(char_t)); + buf[source_length] = 0; // deallocate old buffer (*after* the above to protect against overlapping memory and/or allocation failures) if (header & header_mask) alloc->deallocate_string(dest); - + // the string is now allocated, so set the flag dest = buf; header |= header_mask; @@ -2392,11 +2405,11 @@ PUGI__NS_BEGIN { char_t* end; size_t size; - + gap(): end(0), size(0) { } - + // Push new gap, move s count bytes further (skipping the gap). // Collapse previous gap. void push(char_t*& s, size_t count) @@ -2407,14 +2420,14 @@ PUGI__NS_BEGIN assert(s >= end); memmove(end - size, end, reinterpret_cast(s) - reinterpret_cast(end)); } - + s += count; // end of current gap - + // "merge" two gaps end = s; size += count; } - + // Collapse all gaps, return past-the-end pointer char_t* flush(char_t* s) { @@ -2429,7 +2442,7 @@ PUGI__NS_BEGIN else return s; } }; - + PUGI__FN char_t* strconv_escape(char_t* s, gap& g) { char_t* stre = s + 1; @@ -2461,7 +2474,7 @@ PUGI__NS_BEGIN ch = *++stre; } - + ++stre; } else // &#... (dec code) @@ -2472,7 +2485,7 @@ PUGI__NS_BEGIN for (;;) { - if (static_cast(static_cast(ch) - '0') <= 9) + if (static_cast(ch - '0') <= 9) ucsc = 10 * ucsc + (ch - '0'); else if (ch == ';') break; @@ -2481,7 +2494,7 @@ PUGI__NS_BEGIN ch = *++stre; } - + ++stre; } @@ -2490,7 +2503,7 @@ PUGI__NS_BEGIN #else s = reinterpret_cast(utf8_writer::any(reinterpret_cast(s), ucsc)); #endif - + g.push(s, stre - s); return stre; } @@ -2505,7 +2518,7 @@ PUGI__NS_BEGIN { *s++ = '&'; ++stre; - + g.push(s, stre - s); return stre; } @@ -2530,7 +2543,7 @@ PUGI__NS_BEGIN { *s++ = '>'; ++stre; - + g.push(s, stre - s); return stre; } @@ -2543,7 +2556,7 @@ PUGI__NS_BEGIN { *s++ = '<'; ++stre; - + g.push(s, stre - s); return stre; } @@ -2556,7 +2569,7 @@ PUGI__NS_BEGIN { *s++ = '"'; ++stre; - + g.push(s, stre - s); return stre; } @@ -2566,7 +2579,7 @@ PUGI__NS_BEGIN default: break; } - + return stre; } @@ -2574,7 +2587,7 @@ PUGI__NS_BEGIN #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) - #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } + #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, *alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } #define PUGI__POPNODE() { cursor = cursor->parent; } #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } #define PUGI__SCANWHILE(X) { while (X) ++s; } @@ -2586,21 +2599,21 @@ PUGI__NS_BEGIN PUGI__FN char_t* strconv_comment(char_t* s, char_t endch) { gap g; - + while (true) { PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_comment)); - + if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { *s++ = '\n'; // replace first one with 0x0a - + if (*s == '\n') g.push(s, 1); } else if (s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')) // comment ends here { *g.flush(s) = 0; - + return s + (s[2] == '>' ? 3 : 2); } else if (*s == 0) @@ -2614,21 +2627,21 @@ PUGI__NS_BEGIN PUGI__FN char_t* strconv_cdata(char_t* s, char_t endch) { gap g; - + while (true) { PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_cdata)); - + if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { *s++ = '\n'; // replace first one with 0x0a - + if (*s == '\n') g.push(s, 1); } else if (s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')) // CDATA ends here { *g.flush(s) = 0; - + return s + 1; } else if (*s == 0) @@ -2638,9 +2651,9 @@ PUGI__NS_BEGIN else ++s; } } - + typedef char_t* (*strconv_pcdata_t)(char_t*); - + template struct strconv_pcdata_impl { static char_t* parse(char_t* s) @@ -2662,13 +2675,13 @@ PUGI__NS_BEGIN --end; *end = 0; - + return s + 1; } else if (opt_eol::value && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair { *s++ = '\n'; // replace first one with 0x0a - + if (*s == '\n') g.push(s, 1); } else if (opt_escape::value && *s == '&') @@ -2691,7 +2704,7 @@ PUGI__NS_BEGIN } } }; - + PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) { PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800); @@ -2706,12 +2719,12 @@ PUGI__NS_BEGIN case 5: return strconv_pcdata_impl::parse; case 6: return strconv_pcdata_impl::parse; case 7: return strconv_pcdata_impl::parse; - default: assert(false); return 0; // should not get here + default: assert(false); return 0; // unreachable } } typedef char_t* (*strconv_attribute_t)(char_t*, char_t); - + template struct strconv_attribute_impl { static char_t* parse_wnorm(char_t* s, char_t end_quote) @@ -2722,35 +2735,35 @@ PUGI__NS_BEGIN if (PUGI__IS_CHARTYPE(*s, ct_space)) { char_t* str = s; - + do ++str; while (PUGI__IS_CHARTYPE(*str, ct_space)); - + g.push(s, str - s); } while (true) { PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws | ct_space)); - + if (*s == end_quote) { char_t* str = g.flush(s); - + do *str-- = 0; while (PUGI__IS_CHARTYPE(*str, ct_space)); - + return s + 1; } else if (PUGI__IS_CHARTYPE(*s, ct_space)) { *s++ = ' '; - + if (PUGI__IS_CHARTYPE(*s, ct_space)) { char_t* str = s + 1; while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str; - + g.push(s, str - s); } } @@ -2773,11 +2786,11 @@ PUGI__NS_BEGIN while (true) { PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws)); - + if (*s == end_quote) { *g.flush(s) = 0; - + return s + 1; } else if (PUGI__IS_CHARTYPE(*s, ct_space)) @@ -2785,7 +2798,7 @@ PUGI__NS_BEGIN if (*s == '\r') { *s++ = ' '; - + if (*s == '\n') g.push(s, 1); } else *s++ = ' '; @@ -2809,17 +2822,17 @@ PUGI__NS_BEGIN while (true) { PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); - + if (*s == end_quote) { *g.flush(s) = 0; - + return s + 1; } else if (*s == '\r') { *s++ = '\n'; - + if (*s == '\n') g.push(s, 1); } else if (opt_escape::value && *s == '&') @@ -2841,11 +2854,11 @@ PUGI__NS_BEGIN while (true) { PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); - + if (*s == end_quote) { *g.flush(s) = 0; - + return s + 1; } else if (opt_escape::value && *s == '&') @@ -2864,7 +2877,7 @@ PUGI__NS_BEGIN PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask) { PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); - + switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes) { case 0: return strconv_attribute_impl::parse_simple; @@ -2883,7 +2896,7 @@ PUGI__NS_BEGIN case 13: return strconv_attribute_impl::parse_wnorm; case 14: return strconv_attribute_impl::parse_wnorm; case 15: return strconv_attribute_impl::parse_wnorm; - default: assert(false); return 0; // should not get here + default: assert(false); return 0; // unreachable } } @@ -2898,18 +2911,12 @@ PUGI__NS_BEGIN struct xml_parser { - xml_allocator alloc; - xml_allocator* alloc_state; + xml_allocator* alloc; char_t* error_offset; xml_parse_status error_status; - - xml_parser(xml_allocator* alloc_): alloc(*alloc_), alloc_state(alloc_), error_offset(0), error_status(status_ok) - { - } - ~xml_parser() + xml_parser(xml_allocator* alloc_): alloc(alloc_), error_offset(0), error_status(status_ok) { - *alloc_state = alloc; } // DOCTYPE consists of nested sections of the following possible types: @@ -3236,7 +3243,7 @@ PUGI__NS_BEGIN { strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk); strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); - + char_t ch = 0; xml_node_struct* cursor = root; char_t* mark = s; @@ -3267,10 +3274,10 @@ PUGI__NS_BEGIN while (true) { PUGI__SKIPWS(); // Eat any whitespace. - + if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... { - xml_attribute_struct* a = append_new_attribute(cursor, alloc); // Make space for this attribute. + xml_attribute_struct* a = append_new_attribute(cursor, *alloc); // Make space for this attribute. if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); a->name = s; // Save the offset. @@ -3285,7 +3292,7 @@ PUGI__NS_BEGIN ch = *s; ++s; } - + if (ch == '=') // '<... #=...' { PUGI__SKIPWS(); // Eat any whitespace. @@ -3297,7 +3304,7 @@ PUGI__NS_BEGIN a->value = s; // Save the offset. s = strconv_attribute(s, ch); - + if (!s) PUGI__THROW_ERROR(status_bad_attribute, a->value); // After this line the loop continues from the start; @@ -3312,7 +3319,7 @@ PUGI__NS_BEGIN else if (*s == '/') { ++s; - + if (*s == '>') { PUGI__POPNODE(); @@ -3353,7 +3360,7 @@ PUGI__NS_BEGIN { // we stepped over null terminator, backtrack & handle closing tag --s; - + if (endch != '>') PUGI__THROW_ERROR(status_bad_start_element, s); } else PUGI__THROW_ERROR(status_bad_start_element, s); @@ -3362,20 +3369,22 @@ PUGI__NS_BEGIN { ++s; + mark = s; + char_t* name = cursor->name; - if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, s); - + if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, mark); + while (PUGI__IS_CHARTYPE(*s, ct_symbol)) { - if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, s); + if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, mark); } if (*name) { if (*s == 0 && name[0] == endch && name[1] == 0) PUGI__THROW_ERROR(status_bad_end_element, s); - else PUGI__THROW_ERROR(status_end_element_mismatch, s); + else PUGI__THROW_ERROR(status_end_element_mismatch, mark); } - + PUGI__POPNODE(); // Pop. PUGI__SKIPWS(); @@ -3429,23 +3438,31 @@ PUGI__NS_BEGIN if (!PUGI__OPTSET(parse_trim_pcdata)) s = mark; - + if (cursor->parent || PUGI__OPTSET(parse_fragment)) { - PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. - cursor->value = s; // Save the offset. + if (PUGI__OPTSET(parse_embed_pcdata) && cursor->parent && !cursor->first_child && !cursor->value) + { + cursor->value = s; // Save the offset. + } + else + { + PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. + + cursor->value = s; // Save the offset. + + PUGI__POPNODE(); // Pop since this is a standalone. + } s = strconv_pcdata(s); - - PUGI__POPNODE(); // Pop since this is a standalone. - + if (!*s) break; } else { PUGI__SCANFOR(*s == '<'); // '...<' if (!*s) break; - + ++s; } @@ -3493,14 +3510,14 @@ PUGI__NS_BEGIN // get last child of the root before parsing xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c + 0 : 0; - + // create parser on stack xml_parser parser(static_cast(xmldoc)); // save last character and make buffer zero-terminated (speeds up parsing) char_t endch = buffer[length - 1]; buffer[length - 1] = 0; - + // skip BOM to make sure it does not end up as part of parse output char_t* buffer_data = parse_skip_bom(buffer); @@ -3517,7 +3534,7 @@ PUGI__NS_BEGIN return make_parse_result(status_unrecognized_tag, length - 1); // check if there are any element nodes parsed - xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child; + xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child+ 0; if (!PUGI__OPTSET(parse_fragment) && !has_element_node_siblings(first_root_child_parsed)) return make_parse_result(status_no_document_element, length - 1); @@ -3561,12 +3578,36 @@ PUGI__NS_BEGIN return encoding_utf8; } + template PUGI__FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t* data, size_t length, D, T) + { + PUGI__STATIC_ASSERT(sizeof(char_t) == sizeof(typename D::type)); + + typename T::value_type end = D::process(reinterpret_cast(data), length, dest, T()); + + return static_cast(end - dest) * sizeof(*dest); + } + + template PUGI__FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t* data, size_t length, D, T, bool opt_swap) + { + PUGI__STATIC_ASSERT(sizeof(char_t) == sizeof(typename D::type)); + + typename T::value_type end = D::process(reinterpret_cast(data), length, dest, T()); + + if (opt_swap) + { + for (typename T::value_type i = dest; i != end; ++i) + *i = endian_swap(*i); + } + + return static_cast(end - dest) * sizeof(*dest); + } + #ifdef PUGIXML_WCHAR_MODE PUGI__FN size_t get_valid_length(const char_t* data, size_t length) { if (length < 1) return 0; - // discard last character if it's the lead of a surrogate pair + // discard last character if it's the lead of a surrogate pair return (sizeof(wchar_t) == 2 && static_cast(static_cast(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; } @@ -3579,58 +3620,32 @@ PUGI__NS_BEGIN return length * sizeof(char_t); } - + // convert to utf8 if (encoding == encoding_utf8) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - return static_cast(end - dest); - } + return convert_buffer_output_generic(r_u8, data, length, wchar_decoder(), utf8_writer()); // convert to utf16 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { - uint16_t* dest = r_u16; - - // convert to native utf16 - uint16_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint16_t); + return convert_buffer_output_generic(r_u16, data, length, wchar_decoder(), utf16_writer(), native_encoding != encoding); } // convert to utf32 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { - uint32_t* dest = r_u32; - - // convert to native utf32 - uint32_t* end = utf_decoder::decode_wchar_block(data, length, dest); - - // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint32_t); + return convert_buffer_output_generic(r_u32, data, length, wchar_decoder(), utf32_writer(), native_encoding != encoding); } // convert to latin1 if (encoding == encoding_latin1) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_wchar_block(data, length, dest); + return convert_buffer_output_generic(r_u8, data, length, wchar_decoder(), latin1_writer()); - return static_cast(end - dest); - } - - assert(!"Invalid encoding"); + assert(false && "Invalid encoding"); // unreachable return 0; } #else @@ -3654,43 +3669,22 @@ PUGI__NS_BEGIN { if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) { - uint16_t* dest = r_u16; - - // convert to native utf16 - uint16_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint16_t); + return convert_buffer_output_generic(r_u16, data, length, utf8_decoder(), utf16_writer(), native_encoding != encoding); } if (encoding == encoding_utf32_be || encoding == encoding_utf32_le) { - uint32_t* dest = r_u32; - - // convert to native utf32 - uint32_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); - - // swap if necessary xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be; - if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast(end - dest)); - - return static_cast(end - dest) * sizeof(uint32_t); + return convert_buffer_output_generic(r_u32, data, length, utf8_decoder(), utf32_writer(), native_encoding != encoding); } if (encoding == encoding_latin1) - { - uint8_t* dest = r_u8; - uint8_t* end = utf_decoder::decode_utf8_block(reinterpret_cast(data), length, dest); + return convert_buffer_output_generic(r_u8, data, length, utf8_decoder(), latin1_writer()); - return static_cast(end - dest); - } - - assert(!"Invalid encoding"); + assert(false && "Invalid encoding"); // unreachable return 0; } #endif @@ -3914,10 +3908,10 @@ PUGI__NS_BEGIN while (*s) { const char_t* prev = s; - + // While *s is a usual symbol PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPEX(ss, type)); - + writer.write_buffer(prev, static_cast(s - prev)); switch (*s) @@ -4083,7 +4077,7 @@ PUGI__NS_BEGIN writer.write(' '); } - writer.write_string(a->name ? a->name : default_name); + writer.write_string(a->name ? a->name + 0 : default_name); writer.write('=', '"'); if (a->value) @@ -4096,7 +4090,7 @@ PUGI__NS_BEGIN PUGI__FN bool node_output_start(xml_buffered_writer& writer, xml_node_struct* node, const char_t* indent, size_t indent_length, unsigned int flags, unsigned int depth) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); - const char_t* name = node->name ? node->name : default_name; + const char_t* name = node->name ? node->name + 0 : default_name; writer.write('<'); writer.write_string(name); @@ -4104,24 +4098,61 @@ PUGI__NS_BEGIN if (node->first_attribute) node_output_attributes(writer, node, indent, indent_length, flags, depth); - if (!node->first_child) + // element nodes can have value if parse_embed_pcdata was used + if (!node->value) { - writer.write(' ', '/', '>'); + if (!node->first_child) + { + if (flags & format_no_empty_element_tags) + { + writer.write('>', '<', '/'); + writer.write_string(name); + writer.write('>'); - return false; + return false; + } + else + { + if ((flags & format_raw) == 0) + writer.write(' '); + + writer.write('/', '>'); + + return false; + } + } + else + { + writer.write('>'); + + return true; + } } else { writer.write('>'); - return true; + text_output(writer, node->value, ctx_special_pcdata, flags); + + if (!node->first_child) + { + writer.write('<', '/'); + writer.write_string(name); + writer.write('>'); + + return false; + } + else + { + return true; + } } } PUGI__FN void node_output_end(xml_buffered_writer& writer, xml_node_struct* node) { const char_t* default_name = PUGIXML_TEXT(":anonymous"); - const char_t* name = node->name ? node->name : default_name; + const char_t* name = node->name ? node->name + 0 : default_name; writer.write('<', '/'); writer.write_string(name); @@ -4148,7 +4179,7 @@ PUGI__NS_BEGIN case node_pi: writer.write('<', '?'); - writer.write_string(node->name ? node->name : default_name); + writer.write_string(node->name ? node->name + 0 : default_name); if (node->value) { @@ -4161,7 +4192,7 @@ PUGI__NS_BEGIN case node_declaration: writer.write('<', '?'); - writer.write_string(node->name ? node->name : default_name); + writer.write_string(node->name ? node->name + 0 : default_name); node_output_attributes(writer, node, PUGIXML_TEXT(""), 0, flags | format_raw, 0); writer.write('?', '>'); break; @@ -4180,7 +4211,7 @@ PUGI__NS_BEGIN break; default: - assert(!"Invalid node type"); + assert(false && "Invalid node type"); // unreachable } } @@ -4222,6 +4253,10 @@ PUGI__NS_BEGIN if (node_output_start(writer, node, indent, indent_length, flags, depth)) { + // element nodes can have value if parse_embed_pcdata was used + if (node->value) + indent_flags = 0; + node = node->first_child; depth++; continue; @@ -4355,7 +4390,7 @@ PUGI__NS_BEGIN source_header |= xml_memory_page_contents_shared_mask; } else - strcpy_insitu(dest, header, header_mask, source); + strcpy_insitu(dest, header, header_mask, source, strlength(source)); } } @@ -4388,6 +4423,7 @@ PUGI__NS_BEGIN while (sit && sit != sn) { + // when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop if (sit != dn) { xml_node_struct* copy = append_new_node(dit, alloc, PUGI__NODETYPE(sit)); @@ -4438,39 +4474,96 @@ PUGI__NS_BEGIN } // get value with conversion functions - PUGI__FN int get_integer_base(const char_t* value) + template PUGI__FN PUGI__UNSIGNED_OVERFLOW U string_to_integer(const char_t* value, U minv, U maxv) { + U result = 0; const char_t* s = value; while (PUGI__IS_CHARTYPE(*s, ct_space)) s++; - if (*s == '-') - s++; + bool negative = (*s == '-'); - return (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; + s += (*s == '+' || *s == '-'); + + bool overflow = false; + + if (s[0] == '0' && (s[1] | ' ') == 'x') + { + s += 2; + + // since overflow detection relies on length of the sequence skip leading zeros + while (*s == '0') + s++; + + const char_t* start = s; + + for (;;) + { + if (static_cast(*s - '0') < 10) + result = result * 16 + (*s - '0'); + else if (static_cast((*s | ' ') - 'a') < 6) + result = result * 16 + ((*s | ' ') - 'a' + 10); + else + break; + + s++; + } + + size_t digits = static_cast(s - start); + + overflow = digits > sizeof(U) * 2; + } + else + { + // since overflow detection relies on length of the sequence skip leading zeros + while (*s == '0') + s++; + + const char_t* start = s; + + for (;;) + { + if (static_cast(*s - '0') < 10) + result = result * 10 + (*s - '0'); + else + break; + + s++; + } + + size_t digits = static_cast(s - start); + + PUGI__STATIC_ASSERT(sizeof(U) == 8 || sizeof(U) == 4 || sizeof(U) == 2); + + const size_t max_digits10 = sizeof(U) == 8 ? 20 : sizeof(U) == 4 ? 10 : 5; + const char_t max_lead = sizeof(U) == 8 ? '1' : sizeof(U) == 4 ? '4' : '6'; + const size_t high_bit = sizeof(U) * 8 - 1; + + overflow = digits >= max_digits10 && !(digits == max_digits10 && (*start < max_lead || (*start == max_lead && result >> high_bit))); + } + + if (negative) + { + // Workaround for crayc++ CC-3059: Expected no overflow in routine. + #ifdef _CRAYC + return (overflow || result > ~minv + 1) ? minv : ~result + 1; + #else + return (overflow || result > 0 - minv) ? minv : 0 - result; + #endif + } + else + return (overflow || result > maxv) ? maxv : result; } PUGI__FN int get_value_int(const char_t* value) { - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstol(value, 0, base)); - #else - return static_cast(strtol(value, 0, base)); - #endif + return string_to_integer(value, static_cast(INT_MIN), INT_MAX); } PUGI__FN unsigned int get_value_uint(const char_t* value) { - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - return static_cast(wcstoul(value, 0, base)); - #else - return static_cast(strtoul(value, 0, base)); - #endif + return string_to_integer(value, 0, UINT_MAX); } PUGI__FN double get_value_double(const char_t* value) @@ -4503,118 +4596,117 @@ PUGI__NS_BEGIN #ifdef PUGIXML_HAS_LONG_LONG PUGI__FN long long get_value_llong(const char_t* value) { - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - #ifdef PUGI__MSVC_CRT_VERSION - return _wcstoi64(value, 0, base); - #else - return wcstoll(value, 0, base); - #endif - #else - #ifdef PUGI__MSVC_CRT_VERSION - return _strtoi64(value, 0, base); - #else - return strtoll(value, 0, base); - #endif - #endif + return string_to_integer(value, static_cast(LLONG_MIN), LLONG_MAX); } PUGI__FN unsigned long long get_value_ullong(const char_t* value) { - int base = get_integer_base(value); - - #ifdef PUGIXML_WCHAR_MODE - #ifdef PUGI__MSVC_CRT_VERSION - return _wcstoui64(value, 0, base); - #else - return wcstoull(value, 0, base); - #endif - #else - #ifdef PUGI__MSVC_CRT_VERSION - return _strtoui64(value, 0, base); - #else - return strtoull(value, 0, base); - #endif - #endif + return string_to_integer(value, 0, ULLONG_MAX); } #endif + template PUGI__FN PUGI__UNSIGNED_OVERFLOW char_t* integer_to_string(char_t* begin, char_t* end, U value, bool negative) + { + char_t* result = end - 1; + U rest = negative ? 0 - value : value; + + do + { + *result-- = static_cast('0' + (rest % 10)); + rest /= 10; + } + while (rest); + + assert(result >= begin); + (void)begin; + + *result = '-'; + + return result + !negative; + } + // set value with conversion functions template - PUGI__FN bool set_value_buffer(String& dest, Header& header, uintptr_t header_mask, char (&buf)[128]) + PUGI__FN bool set_value_ascii(String& dest, Header& header, uintptr_t header_mask, char* buf) { #ifdef PUGIXML_WCHAR_MODE char_t wbuf[128]; - impl::widen_ascii(wbuf, buf); + assert(strlen(buf) < sizeof(wbuf) / sizeof(wbuf[0])); - return strcpy_insitu(dest, header, header_mask, wbuf); + size_t offset = 0; + for (; buf[offset]; ++offset) wbuf[offset] = buf[offset]; + + return strcpy_insitu(dest, header, header_mask, wbuf, offset); #else - return strcpy_insitu(dest, header, header_mask, buf); + return strcpy_insitu(dest, header, header_mask, buf, strlen(buf)); #endif } - template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, int value) + template + PUGI__FN bool set_value_integer(String& dest, Header& header, uintptr_t header_mask, U value, bool negative) { - char buf[128]; - sprintf(buf, "%d", value); - - return set_value_buffer(dest, header, header_mask, buf); - } + char_t buf[64]; + char_t* end = buf + sizeof(buf) / sizeof(buf[0]); + char_t* begin = integer_to_string(buf, end, value, negative); - template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned int value) - { - char buf[128]; - sprintf(buf, "%u", value); - - return set_value_buffer(dest, header, header_mask, buf); + return strcpy_insitu(dest, header, header_mask, begin, end - begin); } template PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value) { char buf[128]; - sprintf(buf, "%.9g", value); + PUGI__SNPRINTF(buf, "%.9g", value); - return set_value_buffer(dest, header, header_mask, buf); + return set_value_ascii(dest, header, header_mask, buf); } template PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value) { char buf[128]; - sprintf(buf, "%.17g", value); + PUGI__SNPRINTF(buf, "%.17g", value); - return set_value_buffer(dest, header, header_mask, buf); - } - - template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, bool value) - { - return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - } - -#ifdef PUGIXML_HAS_LONG_LONG - template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, long long value) - { - char buf[128]; - sprintf(buf, "%lld", value); - - return set_value_buffer(dest, header, header_mask, buf); + return set_value_ascii(dest, header, header_mask, buf); } template - PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned long long value) + PUGI__FN bool set_value_bool(String& dest, Header& header, uintptr_t header_mask, bool value) { - char buf[128]; - sprintf(buf, "%llu", value); - - return set_value_buffer(dest, header, header_mask, buf); + return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"), value ? 4 : 5); + } + + PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer) + { + // check input buffer + if (!contents && size) return make_parse_result(status_io_error); + + // get actual encoding + xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); + + // get private buffer + char_t* buffer = 0; + size_t length = 0; + + if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); + + // delete original buffer if we performed a conversion + if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); + + // grab onto buffer if it's our buffer, user is responsible for deallocating contents himself + if (own || buffer != contents) *out_buffer = buffer; + + // store buffer for offset_debug + doc->buffer = buffer; + + // parse + xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options); + + // remember encoding + res.encoding = buffer_encoding; + + return res; } -#endif // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result) @@ -4644,7 +4736,7 @@ PUGI__NS_BEGIN // check for I/O errors if (length < 0) return status_io_error; - + // check for overflow size_t result = static_cast(length); @@ -4657,7 +4749,7 @@ PUGI__NS_BEGIN } // This function assumes that buffer has extra sizeof(char_t) writable bytes after size - PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding) + PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding) { // We only need to zero-terminate if encoding conversion does not do it for us #ifdef PUGIXML_WCHAR_MODE @@ -4681,7 +4773,7 @@ PUGI__NS_BEGIN return size; } - PUGI__FN xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding) + PUGI__FN xml_parse_result load_file_impl(xml_document_struct* doc, FILE* file, unsigned int options, xml_encoding encoding, char_t** out_buffer) { if (!file) return make_parse_result(status_file_not_found); @@ -4689,7 +4781,7 @@ PUGI__NS_BEGIN size_t size = 0; xml_parse_status size_status = get_file_size(file, size); if (size_status != status_ok) return make_parse_result(size_status); - + size_t max_suffix_size = sizeof(char_t); // allocate buffer for the whole file @@ -4706,8 +4798,13 @@ PUGI__NS_BEGIN } xml_encoding real_encoding = get_buffer_encoding(encoding, contents, size); - - return doc.load_buffer_inplace_own(contents, zero_terminate_buffer(contents, size, real_encoding), options, real_encoding); + + return load_buffer_impl(doc, doc, contents, zero_terminate_buffer(contents, size, real_encoding), options, real_encoding, true, true, out_buffer); + } + + PUGI__FN void close_file(FILE* file) + { + fclose(file); } #ifndef PUGIXML_NO_STL @@ -4717,7 +4814,7 @@ PUGI__NS_BEGIN { void* memory = xml_memory::allocate(sizeof(xml_stream_chunk)); if (!memory) return 0; - + return new (memory) xml_stream_chunk(); } @@ -4827,14 +4924,14 @@ PUGI__NS_BEGIN // return buffer size_t actual_length = static_cast(stream.gcount()); assert(actual_length <= read_length); - + *out_buffer = buffer.release(); *out_size = actual_length * sizeof(T); return status_ok; } - template PUGI__FN xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding) + template PUGI__FN xml_parse_result load_stream_impl(xml_document_struct* doc, std::basic_istream& stream, unsigned int options, xml_encoding encoding, char_t** out_buffer) { void* buffer = 0; size_t size = 0; @@ -4855,8 +4952,8 @@ PUGI__NS_BEGIN if (status != status_ok) return make_parse_result(status); xml_encoding real_encoding = get_buffer_encoding(encoding, buffer, size); - - return doc.load_buffer_inplace_own(buffer, zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding); + + return load_buffer_impl(doc, doc, buffer, zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding, true, true, out_buffer); } #endif @@ -4917,37 +5014,21 @@ PUGI__NS_BEGIN return ferror(file) == 0; } - PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer) + struct name_null_sentry { - // check input buffer - if (!contents && size) return make_parse_result(status_io_error); + xml_node_struct* node; + char_t* name; - // get actual encoding - xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); + name_null_sentry(xml_node_struct* node_): node(node_), name(node_->name) + { + node->name = 0; + } - // get private buffer - char_t* buffer = 0; - size_t length = 0; - - if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); - - // delete original buffer if we performed a conversion - if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); - - // grab onto buffer if it's our buffer, user is responsible for deallocating contents himself - if (own || buffer != contents) *out_buffer = buffer; - - // store buffer for offset_debug - doc->buffer = buffer; - - // parse - xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options); - - // remember encoding - res.encoding = buffer_encoding; - - return res; - } + ~name_null_sentry() + { + node->name = name; + } + }; PUGI__NS_END namespace pugi @@ -4991,7 +5072,7 @@ namespace pugi PUGI__FN xml_tree_walker::xml_tree_walker(): _depth(0) { } - + PUGI__FN xml_tree_walker::~xml_tree_walker() { } @@ -5037,7 +5118,7 @@ namespace pugi { return (_attr == r._attr); } - + PUGI__FN bool xml_attribute::operator!=(const xml_attribute& r) const { return (_attr != r._attr); @@ -5047,17 +5128,17 @@ namespace pugi { return (_attr < r._attr); } - + PUGI__FN bool xml_attribute::operator>(const xml_attribute& r) const { return (_attr > r._attr); } - + PUGI__FN bool xml_attribute::operator<=(const xml_attribute& r) const { return (_attr <= r._attr); } - + PUGI__FN bool xml_attribute::operator>=(const xml_attribute& r) const { return (_attr >= r._attr); @@ -5075,7 +5156,7 @@ namespace pugi PUGI__FN const char_t* xml_attribute::as_string(const char_t* def) const { - return (_attr && _attr->value) ? _attr->value : def; + return (_attr && _attr->value) ? _attr->value + 0 : def; } PUGI__FN int xml_attribute::as_int(int def) const @@ -5145,7 +5226,7 @@ namespace pugi set_value(rhs); return *this; } - + PUGI__FN xml_attribute& xml_attribute::operator=(int rhs) { set_value(rhs); @@ -5158,12 +5239,24 @@ namespace pugi return *this; } + PUGI__FN xml_attribute& xml_attribute::operator=(long rhs) + { + set_value(rhs); + return *this; + } + + PUGI__FN xml_attribute& xml_attribute::operator=(unsigned long rhs) + { + set_value(rhs); + return *this; + } + PUGI__FN xml_attribute& xml_attribute::operator=(double rhs) { set_value(rhs); return *this; } - + PUGI__FN xml_attribute& xml_attribute::operator=(float rhs) { set_value(rhs); @@ -5193,29 +5286,43 @@ namespace pugi PUGI__FN bool xml_attribute::set_name(const char_t* rhs) { if (!_attr) return false; - - return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs); + + return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs)); } - + PUGI__FN bool xml_attribute::set_value(const char_t* rhs) { if (!_attr) return false; - return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)); } PUGI__FN bool xml_attribute::set_value(int rhs) { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0); } PUGI__FN bool xml_attribute::set_value(unsigned int rhs) { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); + } + + PUGI__FN bool xml_attribute::set_value(long rhs) + { + if (!_attr) return false; + + return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0); + } + + PUGI__FN bool xml_attribute::set_value(unsigned long rhs) + { + if (!_attr) return false; + + return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); } PUGI__FN bool xml_attribute::set_value(double rhs) @@ -5224,7 +5331,7 @@ namespace pugi return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } - + PUGI__FN bool xml_attribute::set_value(float rhs) { if (!_attr) return false; @@ -5236,7 +5343,7 @@ namespace pugi { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_bool(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); } #ifdef PUGIXML_HAS_LONG_LONG @@ -5244,14 +5351,14 @@ namespace pugi { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0); } PUGI__FN bool xml_attribute::set_value(unsigned long long rhs) { if (!_attr) return false; - return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); } #endif @@ -5274,7 +5381,7 @@ namespace pugi PUGI__FN xml_node::xml_node(xml_node_struct* p): _root(p) { } - + PUGI__FN static void unspecified_bool_xml_node(xml_node***) { } @@ -5298,7 +5405,7 @@ namespace pugi { return iterator(0, _root); } - + PUGI__FN xml_node::attribute_iterator xml_node::attributes_begin() const { return attribute_iterator(_root ? _root->first_attribute + 0 : 0, _root); @@ -5308,7 +5415,7 @@ namespace pugi { return attribute_iterator(0, _root); } - + PUGI__FN xml_object_range xml_node::children() const { return xml_object_range(begin(), end()); @@ -5338,17 +5445,17 @@ namespace pugi { return (_root < r._root); } - + PUGI__FN bool xml_node::operator>(const xml_node& r) const { return (_root > r._root); } - + PUGI__FN bool xml_node::operator<=(const xml_node& r) const { return (_root <= r._root); } - + PUGI__FN bool xml_node::operator>=(const xml_node& r) const { return (_root >= r._root); @@ -5358,7 +5465,7 @@ namespace pugi { return !_root; } - + PUGI__FN const char_t* xml_node::name() const { return (_root && _root->name) ? _root->name + 0 : PUGIXML_TEXT(""); @@ -5368,12 +5475,12 @@ namespace pugi { return _root ? PUGI__NODETYPE(_root) : node_null; } - + PUGI__FN const char_t* xml_node::value() const { return (_root && _root->value) ? _root->value + 0 : PUGIXML_TEXT(""); } - + PUGI__FN xml_node xml_node::child(const char_t* name_) const { if (!_root) return xml_node(); @@ -5391,14 +5498,14 @@ namespace pugi for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) if (i->name && impl::strequal(name_, i->name)) return xml_attribute(i); - + return xml_attribute(); } - + PUGI__FN xml_node xml_node::next_sibling(const char_t* name_) const { if (!_root) return xml_node(); - + for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) if (i->name && impl::strequal(name_, i->name)) return xml_node(i); @@ -5413,7 +5520,7 @@ namespace pugi PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const { if (!_root) return xml_node(); - + for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c) if (i->name && impl::strequal(name_, i->name)) return xml_node(i); @@ -5456,7 +5563,7 @@ namespace pugi PUGI__FN xml_node xml_node::previous_sibling() const { if (!_root) return xml_node(); - + if (_root->prev_sibling_c->next_sibling) return xml_node(_root->prev_sibling_c); else return xml_node(); } @@ -5479,7 +5586,11 @@ namespace pugi PUGI__FN const char_t* xml_node::child_value() const { if (!_root) return PUGIXML_TEXT(""); - + + // element nodes can have value if parse_embed_pcdata was used + if (PUGI__NODETYPE(_root) == node_element && _root->value) + return _root->value; + for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) if (impl::is_text_node(i) && i->value) return i->value; @@ -5514,28 +5625,28 @@ namespace pugi PUGI__FN bool xml_node::set_name(const char_t* rhs) { - static const bool has_name[] = { false, false, true, false, false, false, true, true, false }; + xml_node_type type_ = _root ? PUGI__NODETYPE(_root) : node_null; - if (!_root || !has_name[PUGI__NODETYPE(_root)]) + if (type_ != node_element && type_ != node_pi && type_ != node_declaration) return false; - return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs); + return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs)); } - + PUGI__FN bool xml_node::set_value(const char_t* rhs) { - static const bool has_value[] = { false, false, false, true, true, true, true, false, true }; + xml_node_type type_ = _root ? PUGI__NODETYPE(_root) : node_null; - if (!_root || !has_value[PUGI__NODETYPE(_root)]) + if (type_ != node_pcdata && type_ != node_cdata && type_ != node_comment && type_ != node_pi && type_ != node_doctype) return false; - return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs); + return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)); } PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) { if (!impl::allow_insert_attribute(type())) return xml_attribute(); - + impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_attribute(); @@ -5545,14 +5656,14 @@ namespace pugi impl::append_attribute(a._attr, _root); a.set_name(name_); - + return a; } PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) { if (!impl::allow_insert_attribute(type())) return xml_attribute(); - + impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_attribute(); @@ -5570,7 +5681,7 @@ namespace pugi { if (!impl::allow_insert_attribute(type())) return xml_attribute(); if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); - + impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_attribute(); @@ -5588,7 +5699,7 @@ namespace pugi { if (!impl::allow_insert_attribute(type())) return xml_attribute(); if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); - + impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_attribute(); @@ -5675,7 +5786,7 @@ namespace pugi PUGI__FN xml_node xml_node::append_child(xml_node_type type_) { if (!impl::allow_insert_child(type(), type_)) return xml_node(); - + impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_node(); @@ -5695,12 +5806,12 @@ namespace pugi impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_node(); - + xml_node n(impl::allocate_node(alloc, type_)); if (!n) return xml_node(); impl::prepend_node(n._root, _root); - + if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); return n; @@ -5713,7 +5824,7 @@ namespace pugi impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_node(); - + xml_node n(impl::allocate_node(alloc, type_)); if (!n) return xml_node(); @@ -5731,7 +5842,7 @@ namespace pugi impl::xml_allocator& alloc = impl::get_allocator(_root); if (!alloc.reserve()) return xml_node(); - + xml_node n(impl::allocate_node(alloc, type_)); if (!n) return xml_node(); @@ -5963,31 +6074,27 @@ namespace pugi // disable document_buffer_order optimization since in a document with multiple buffers comparing buffer pointers does not make sense doc->header |= impl::xml_memory_page_contents_shared_mask; - + // get extra buffer element (we'll store the document fragment buffer there so that we can deallocate it later) impl::xml_memory_page* page = 0; - impl::xml_extra_buffer* extra = static_cast(doc->allocate_memory(sizeof(impl::xml_extra_buffer), page)); + impl::xml_extra_buffer* extra = static_cast(doc->allocate_memory(sizeof(impl::xml_extra_buffer) + sizeof(void*), page)); (void)page; if (!extra) return impl::make_parse_result(status_out_of_memory); + #ifdef PUGIXML_COMPACT + // align the memory block to a pointer boundary; this is required for compact mode where memory allocations are only 4b aligned + // note that this requires up to sizeof(void*)-1 additional memory, which the allocation above takes into account + extra = reinterpret_cast((reinterpret_cast(extra) + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1)); + #endif + // add extra buffer to the list extra->buffer = 0; extra->next = doc->extra_buffers; doc->extra_buffers = extra; // name of the root has to be NULL before parsing - otherwise closing node mismatches will not be detected at the top level - struct name_sentry - { - xml_node_struct* node; - char_t* name; - - ~name_sentry() { node->name = name; } - }; - - name_sentry sentry = { _root, _root->name }; - - sentry.node->name = 0; + impl::name_null_sentry sentry(_root); return impl::load_buffer_impl(doc, _root, const_cast(contents), size, options, encoding, false, false, &extra->buffer); } @@ -5995,7 +6102,7 @@ namespace pugi PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const { if (!_root) return xml_node(); - + for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) if (i->name && impl::strequal(name_, i->name)) { @@ -6010,7 +6117,7 @@ namespace pugi PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const { if (!_root) return xml_node(); - + for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value + 0 : PUGIXML_TEXT(""))) @@ -6040,7 +6147,7 @@ namespace pugi if (j != _root) result[--offset] = delimiter; - if (j->name && *j->name) + if (j->name) { size_t length = impl::strlength(j->name); @@ -6059,7 +6166,7 @@ namespace pugi { xml_node found = *this; // Current search context. - if (!_root || !path_ || !path_[0]) return found; + if (!_root || !path_[0]) return found; if (path_[0] == delimiter) { @@ -6105,48 +6212,47 @@ namespace pugi PUGI__FN bool xml_node::traverse(xml_tree_walker& walker) { walker._depth = -1; - - xml_node arg_begin = *this; + + xml_node arg_begin(_root); if (!walker.begin(arg_begin)) return false; - xml_node cur = first_child(); - + xml_node_struct* cur = _root ? _root->first_child + 0 : 0; + if (cur) { ++walker._depth; - do + do { - xml_node arg_for_each = cur; + xml_node arg_for_each(cur); if (!walker.for_each(arg_for_each)) return false; - - if (cur.first_child()) + + if (cur->first_child) { ++walker._depth; - cur = cur.first_child(); + cur = cur->first_child; } - else if (cur.next_sibling()) - cur = cur.next_sibling(); + else if (cur->next_sibling) + cur = cur->next_sibling; else { - // Borland C++ workaround - while (!cur.next_sibling() && cur != *this && !cur.parent().empty()) + while (!cur->next_sibling && cur != _root && cur->parent) { --walker._depth; - cur = cur.parent(); + cur = cur->parent; } - - if (cur != *this) - cur = cur.next_sibling(); + + if (cur != _root) + cur = cur->next_sibling; } } - while (cur && cur != *this); + while (cur && cur != _root); } assert(walker._depth == -1); - xml_node arg_end = *this; + xml_node arg_end(_root); return walker.end(arg_end); } @@ -6213,6 +6319,7 @@ namespace pugi return _root->value && (_root->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0 ? _root->value - doc.buffer : -1; default: + assert(false && "Invalid node type"); // unreachable return -1; } } @@ -6237,6 +6344,10 @@ namespace pugi { if (!_root || impl::is_text_node(_root)) return _root; + // element nodes can have value if parse_embed_pcdata was used + if (PUGI__NODETYPE(_root) == node_element && _root->value) + return _root; + for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling) if (impl::is_text_node(node)) return node; @@ -6286,7 +6397,7 @@ namespace pugi { xml_node_struct* d = _data(); - return (d && d->value) ? d->value : def; + return (d && d->value) ? d->value + 0 : def; } PUGI__FN int xml_text::as_int(int def) const @@ -6344,21 +6455,35 @@ namespace pugi { xml_node_struct* dn = _data_new(); - return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)) : false; } PUGI__FN bool xml_text::set(int rhs) { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false; } PUGI__FN bool xml_text::set(unsigned int rhs) { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false; + } + + PUGI__FN bool xml_text::set(long rhs) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false; + } + + PUGI__FN bool xml_text::set(unsigned long rhs) + { + xml_node_struct* dn = _data_new(); + + return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false; } PUGI__FN bool xml_text::set(float rhs) @@ -6379,7 +6504,7 @@ namespace pugi { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_bool(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; } #ifdef PUGIXML_HAS_LONG_LONG @@ -6387,14 +6512,14 @@ namespace pugi { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false; } PUGI__FN bool xml_text::set(unsigned long long rhs) { xml_node_struct* dn = _data_new(); - return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; + return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false; } #endif @@ -6416,6 +6541,18 @@ namespace pugi return *this; } + PUGI__FN xml_text& xml_text::operator=(long rhs) + { + set(rhs); + return *this; + } + + PUGI__FN xml_text& xml_text::operator=(unsigned long rhs) + { + set(rhs); + return *this; + } + PUGI__FN xml_text& xml_text::operator=(double rhs) { set(rhs); @@ -6481,7 +6618,7 @@ namespace pugi { return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; } - + PUGI__FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const { return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; @@ -6496,7 +6633,7 @@ namespace pugi PUGI__FN xml_node* xml_node_iterator::operator->() const { assert(_wrap._root); - return const_cast(&_wrap); // BCC32 workaround + return const_cast(&_wrap); // BCC5 workaround } PUGI__FN const xml_node_iterator& xml_node_iterator::operator++() @@ -6542,7 +6679,7 @@ namespace pugi { return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root; } - + PUGI__FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const { return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root; @@ -6557,7 +6694,7 @@ namespace pugi PUGI__FN xml_attribute* xml_attribute_iterator::operator->() const { assert(_wrap._attr); - return const_cast(&_wrap); // BCC32 workaround + return const_cast(&_wrap); // BCC5 workaround } PUGI__FN const xml_attribute_iterator& xml_attribute_iterator::operator++() @@ -6618,7 +6755,7 @@ namespace pugi PUGI__FN xml_node* xml_named_node_iterator::operator->() const { assert(_wrap._root); - return const_cast(&_wrap); // BCC32 workaround + return const_cast(&_wrap); // BCC5 workaround } PUGI__FN const xml_named_node_iterator& xml_named_node_iterator::operator++() @@ -6699,18 +6836,37 @@ namespace pugi PUGI__FN xml_document::xml_document(): _buffer(0) { - create(); + _create(); } PUGI__FN xml_document::~xml_document() { - destroy(); + _destroy(); } +#ifdef PUGIXML_HAS_MOVE + PUGI__FN xml_document::xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT: _buffer(0) + { + _create(); + _move(rhs); + } + + PUGI__FN xml_document& xml_document::operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT + { + if (this == &rhs) return *this; + + _destroy(); + _create(); + _move(rhs); + + return *this; + } +#endif + PUGI__FN void xml_document::reset() { - destroy(); - create(); + _destroy(); + _create(); } PUGI__FN void xml_document::reset(const xml_document& proto) @@ -6721,31 +6877,30 @@ namespace pugi append_copy(cur); } - PUGI__FN void xml_document::create() + PUGI__FN void xml_document::_create() { assert(!_root); #ifdef PUGIXML_COMPACT - const size_t page_offset = sizeof(uint32_t); + // space for page marker for the first page (uint32_t), rounded up to pointer size; assumes pointers are at least 32-bit + const size_t page_offset = sizeof(void*); #else const size_t page_offset = 0; #endif // initialize sentinel page - PUGI__STATIC_ASSERT(sizeof(impl::xml_memory_page) + sizeof(impl::xml_document_struct) + impl::xml_memory_page_alignment - sizeof(void*) + page_offset <= sizeof(_memory)); - - // align upwards to page boundary - void* page_memory = reinterpret_cast((reinterpret_cast(_memory) + (impl::xml_memory_page_alignment - 1)) & ~(impl::xml_memory_page_alignment - 1)); + PUGI__STATIC_ASSERT(sizeof(impl::xml_memory_page) + sizeof(impl::xml_document_struct) + page_offset <= sizeof(_memory)); // prepare page structure - impl::xml_memory_page* page = impl::xml_memory_page::construct(page_memory); + impl::xml_memory_page* page = impl::xml_memory_page::construct(_memory); assert(page); page->busy_size = impl::xml_memory_page_size; // setup first page marker #ifdef PUGIXML_COMPACT - page->compact_page_marker = reinterpret_cast(reinterpret_cast(page) + sizeof(impl::xml_memory_page)); + // round-trip through void* to avoid 'cast increases required alignment of target type' warning + page->compact_page_marker = reinterpret_cast(static_cast(reinterpret_cast(page) + sizeof(impl::xml_memory_page))); *page->compact_page_marker = sizeof(impl::xml_memory_page); #endif @@ -6756,11 +6911,16 @@ namespace pugi // setup sentinel page page->allocator = static_cast(_root); + // setup hash table pointer in allocator + #ifdef PUGIXML_COMPACT + page->allocator->_hash = &static_cast(_root)->hash; + #endif + // verify the document allocation assert(reinterpret_cast(_root) + sizeof(impl::xml_document_struct) <= _memory + sizeof(_memory)); } - PUGI__FN void xml_document::destroy() + PUGI__FN void xml_document::_destroy() { assert(_root); @@ -6799,19 +6959,126 @@ namespace pugi _root = 0; } +#ifdef PUGIXML_HAS_MOVE + PUGI__FN void xml_document::_move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT + { + impl::xml_document_struct* doc = static_cast(_root); + impl::xml_document_struct* other = static_cast(rhs._root); + + // save first child pointer for later; this needs hash access + xml_node_struct* other_first_child = other->first_child; + + #ifdef PUGIXML_COMPACT + // reserve space for the hash table up front; this is the only operation that can fail + // if it does, we have no choice but to throw (if we have exceptions) + if (other_first_child) + { + size_t other_children = 0; + for (xml_node_struct* node = other_first_child; node; node = node->next_sibling) + other_children++; + + // in compact mode, each pointer assignment could result in a hash table request + // during move, we have to relocate document first_child and parents of all children + // normally there's just one child and its parent has a pointerless encoding but + // we assume the worst here + if (!other->_hash->reserve(other_children + 1)) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return; + #else + throw std::bad_alloc(); + #endif + } + } + #endif + + // move allocation state + doc->_root = other->_root; + doc->_busy_size = other->_busy_size; + + // move buffer state + doc->buffer = other->buffer; + doc->extra_buffers = other->extra_buffers; + _buffer = rhs._buffer; + + #ifdef PUGIXML_COMPACT + // move compact hash; note that the hash table can have pointers to other but they will be "inactive", similarly to nodes removed with remove_child + doc->hash = other->hash; + doc->_hash = &doc->hash; + + // make sure we don't access other hash up until the end when we reinitialize other document + other->_hash = 0; + #endif + + // move page structure + impl::xml_memory_page* doc_page = PUGI__GETPAGE(doc); + assert(doc_page && !doc_page->prev && !doc_page->next); + + impl::xml_memory_page* other_page = PUGI__GETPAGE(other); + assert(other_page && !other_page->prev); + + // relink pages since root page is embedded into xml_document + if (impl::xml_memory_page* page = other_page->next) + { + assert(page->prev == other_page); + + page->prev = doc_page; + + doc_page->next = page; + other_page->next = 0; + } + + // make sure pages point to the correct document state + for (impl::xml_memory_page* page = doc_page->next; page; page = page->next) + { + assert(page->allocator == other); + + page->allocator = doc; + + #ifdef PUGIXML_COMPACT + // this automatically migrates most children between documents and prevents ->parent assignment from allocating + if (page->compact_shared_parent == other) + page->compact_shared_parent = doc; + #endif + } + + // move tree structure + assert(!doc->first_child); + + doc->first_child = other_first_child; + + for (xml_node_struct* node = other_first_child; node; node = node->next_sibling) + { + #ifdef PUGIXML_COMPACT + // most children will have migrated when we reassigned compact_shared_parent + assert(node->parent == other || node->parent == doc); + + node->parent = doc; + #else + assert(node->parent == other); + node->parent = doc; + #endif + } + + // reset other document + new (other) impl::xml_document_struct(PUGI__GETPAGE(other)); + rhs._buffer = 0; + } +#endif + #ifndef PUGIXML_NO_STL PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options, xml_encoding encoding) { reset(); - return impl::load_stream_impl(*this, stream, options, encoding); + return impl::load_stream_impl(static_cast(_root), stream, options, encoding, &_buffer); } PUGI__FN xml_parse_result xml_document::load(std::basic_istream >& stream, unsigned int options) { reset(); - return impl::load_stream_impl(*this, stream, options, encoding_wchar); + return impl::load_stream_impl(static_cast(_root), stream, options, encoding_wchar, &_buffer); } #endif @@ -6837,9 +7104,9 @@ namespace pugi reset(); using impl::auto_deleter; // MSVC7 workaround - auto_deleter file(fopen(path_, "rb"), fclose); + auto_deleter file(fopen(path_, "rb"), impl::close_file); - return impl::load_file_impl(*this, file.data, options, encoding); + return impl::load_file_impl(static_cast(_root), file.data, options, encoding, &_buffer); } PUGI__FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding) @@ -6847,9 +7114,9 @@ namespace pugi reset(); using impl::auto_deleter; // MSVC7 workaround - auto_deleter file(impl::open_file_wide(path_, L"rb"), fclose); + auto_deleter file(impl::open_file_wide(path_, L"rb"), impl::close_file); - return impl::load_file_impl(*this, file.data, options, encoding); + return impl::load_file_impl(static_cast(_root), file.data, options, encoding, &_buffer); } PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) @@ -6920,7 +7187,7 @@ namespace pugi PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { using impl::auto_deleter; // MSVC7 workaround - auto_deleter file(fopen(path_, (flags & format_save_file_text) ? "w" : "wb"), fclose); + auto_deleter file(fopen(path_, (flags & format_save_file_text) ? "w" : "wb"), impl::close_file); return impl::save_file_impl(*this, file.data, indent, flags, encoding); } @@ -6928,7 +7195,7 @@ namespace pugi PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const { using impl::auto_deleter; // MSVC7 workaround - auto_deleter file(impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"), fclose); + auto_deleter file(impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"), impl::close_file); return impl::save_file_impl(*this, file.data, indent, flags, encoding); } @@ -6956,14 +7223,14 @@ namespace pugi { return impl::as_utf8_impl(str.c_str(), str.size()); } - + PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const char* str) { assert(str); return impl::as_wide_impl(str, strlen(str)); } - + PUGI__FN std::basic_string PUGIXML_FUNCTION as_wide(const std::string& str) { return impl::as_wide_impl(str.c_str(), str.size()); @@ -7095,7 +7362,7 @@ PUGI__NS_BEGIN if (begin == end) return begin; // last written element - I write = begin++; + I write = begin++; // merge unique elements while (begin != end) @@ -7110,134 +7377,76 @@ PUGI__NS_BEGIN return write + 1; } - template void copy_backwards(I begin, I end, I target) + template void insertion_sort(T* begin, T* end, const Pred& pred) { - while (begin != end) *--target = *--end; - } + if (begin == end) + return; - template void insertion_sort(I begin, I end, const Pred& pred, T*) - { - assert(begin != end); - - for (I it = begin + 1; it != end; ++it) + for (T* it = begin + 1; it != end; ++it) { T val = *it; + T* hole = it; - if (pred(val, *begin)) + // move hole backwards + while (hole > begin && pred(val, *(hole - 1))) { - // move to front - copy_backwards(begin, it, it + 1); - *begin = val; + *hole = *(hole - 1); + hole--; } + + // fill hole with element + *hole = val; + } + } + + template I median3(I first, I middle, I last, const Pred& pred) + { + if (pred(*middle, *first)) swap(middle, first); + if (pred(*last, *middle)) swap(last, middle); + if (pred(*middle, *first)) swap(middle, first); + + return middle; + } + + template void partition3(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend) + { + // invariant: array is split into 4 groups: = < ? > (each variable denotes the boundary between the groups) + T* eq = begin; + T* lt = begin; + T* gt = end; + + while (lt < gt) + { + if (pred(*lt, pivot)) + lt++; + else if (*lt == pivot) + swap(*eq++, *lt++); else - { - I hole = it; - - // move hole backwards - while (pred(val, *(hole - 1))) - { - *hole = *(hole - 1); - hole--; - } - - // fill hole with element - *hole = val; - } + swap(*lt, *--gt); } - } - // std variant for elements with == - template void partition(I begin, I middle, I end, const Pred& pred, I* out_eqbeg, I* out_eqend) - { - I eqbeg = middle, eqend = middle + 1; + // we now have just 4 groups: = < >; move equal elements to the middle + T* eqbeg = gt; - // expand equal range - while (eqbeg != begin && *(eqbeg - 1) == *eqbeg) --eqbeg; - while (eqend != end && *eqend == *eqbeg) ++eqend; + for (T* it = begin; it != eq; ++it) + swap(*it, *--eqbeg); - // process outer elements - I ltend = eqbeg, gtbeg = eqend; - - for (;;) - { - // find the element from the right side that belongs to the left one - for (; gtbeg != end; ++gtbeg) - if (!pred(*eqbeg, *gtbeg)) - { - if (*gtbeg == *eqbeg) swap(*gtbeg, *eqend++); - else break; - } - - // find the element from the left side that belongs to the right one - for (; ltend != begin; --ltend) - if (!pred(*(ltend - 1), *eqbeg)) - { - if (*eqbeg == *(ltend - 1)) swap(*(ltend - 1), *--eqbeg); - else break; - } - - // scanned all elements - if (gtbeg == end && ltend == begin) - { - *out_eqbeg = eqbeg; - *out_eqend = eqend; - return; - } - - // make room for elements by moving equal area - if (gtbeg == end) - { - if (--ltend != --eqbeg) swap(*ltend, *eqbeg); - swap(*eqbeg, *--eqend); - } - else if (ltend == begin) - { - if (eqend != gtbeg) swap(*eqbeg, *eqend); - ++eqend; - swap(*gtbeg++, *eqbeg++); - } - else swap(*gtbeg++, *--ltend); - } - } - - template void median3(I first, I middle, I last, const Pred& pred) - { - if (pred(*middle, *first)) swap(*middle, *first); - if (pred(*last, *middle)) swap(*last, *middle); - if (pred(*middle, *first)) swap(*middle, *first); - } - - template void median(I first, I middle, I last, const Pred& pred) - { - if (last - first <= 40) - { - // median of three for small chunks - median3(first, middle, last, pred); - } - else - { - // median of nine - size_t step = (last - first + 1) / 8; - - median3(first, first + step, first + 2 * step, pred); - median3(middle - step, middle, middle + step, pred); - median3(last - 2 * step, last - step, last, pred); - median3(first + step, middle, last - step, pred); - } + *out_eqbeg = eqbeg; + *out_eqend = gt; } template void sort(I begin, I end, const Pred& pred) { // sort large chunks - while (end - begin > 32) + while (end - begin > 16) { // find median element I middle = begin + (end - begin) / 2; - median(begin, middle, end - 1, pred); + I median = median3(begin, middle, end - 1, pred); // partition in three chunks (< = >) I eqbeg, eqend; - partition(begin, middle, end, pred, &eqbeg, &eqend); + partition3(begin, end, *median, pred, &eqbeg, &eqend); // loop on larger half if (eqbeg - begin > end - eqend) @@ -7253,7 +7462,7 @@ PUGI__NS_BEGIN } // insertion sort small chunk - if (begin != end) insertion_sort(begin, end, pred, &*begin); + insertion_sort(begin, end, pred); } PUGI__NS_END @@ -7270,7 +7479,7 @@ PUGI__NS_BEGIN static const uintptr_t xpath_memory_block_alignment = sizeof(double) > sizeof(void*) ? sizeof(double) : sizeof(void*); struct xpath_memory_block - { + { xpath_memory_block* next; size_t capacity; @@ -7280,25 +7489,18 @@ PUGI__NS_BEGIN double alignment; }; }; - - class xpath_allocator + + struct xpath_allocator { xpath_memory_block* _root; size_t _root_size; + bool* _error; - public: - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf* error_handler; - #endif - - xpath_allocator(xpath_memory_block* root, size_t root_size = 0): _root(root), _root_size(root_size) + xpath_allocator(xpath_memory_block* root, bool* error = 0): _root(root), _root_size(0), _error(error) { - #ifdef PUGIXML_NO_EXCEPTIONS - error_handler = 0; - #endif } - - void* allocate_nothrow(size_t size) + + void* allocate(size_t size) { // round size up to block alignment boundary size = (size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1); @@ -7319,35 +7521,22 @@ PUGI__NS_BEGIN size_t block_size = block_capacity + offsetof(xpath_memory_block, data); xpath_memory_block* block = static_cast(xml_memory::allocate(block_size)); - if (!block) return 0; - + if (!block) + { + if (_error) *_error = true; + return 0; + } + block->next = _root; block->capacity = block_capacity; - + _root = block; _root_size = size; - + return block->data; } } - void* allocate(size_t size) - { - void* result = allocate_nothrow(size); - - if (!result) - { - #ifdef PUGIXML_NO_EXCEPTIONS - assert(error_handler); - longjmp(*error_handler, 1); - #else - throw std::bad_alloc(); - #endif - } - - return result; - } - void* reallocate(void* ptr, size_t old_size, size_t new_size) { // round size up to block alignment boundary @@ -7357,33 +7546,35 @@ PUGI__NS_BEGIN // we can only reallocate the last object assert(ptr == 0 || static_cast(ptr) + old_size == &_root->data[0] + _root_size); - // adjust root size so that we have not allocated the object at all - bool only_object = (_root_size == old_size); + // try to reallocate the object inplace + if (ptr && _root_size - old_size + new_size <= _root->capacity) + { + _root_size = _root_size - old_size + new_size; + return ptr; + } - if (ptr) _root_size -= old_size; - - // allocate a new version (this will obviously reuse the memory if possible) + // allocate a new block void* result = allocate(new_size); - assert(result); + if (!result) return 0; // we have a new block - if (result != ptr && ptr) + if (ptr) { - // copy old data + // copy old data (we only support growing) assert(new_size >= old_size); memcpy(result, ptr, old_size); // free the previous page if it had no other objects - if (only_object) - { - assert(_root->data == result); - assert(_root->next); + assert(_root->data == result); + assert(_root->next); + if (_root->next->data == ptr) + { + // deallocate the whole page, unless it was the first one xpath_memory_block* next = _root->next->next; if (next) { - // deallocate the whole page, unless it was the first one xml_memory::deallocate(_root->next); _root->next = next; } @@ -7455,22 +7646,15 @@ PUGI__NS_BEGIN xpath_allocator result; xpath_allocator temp; xpath_stack stack; + bool oom; - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf error_handler; - #endif - - xpath_stack_data(): result(blocks + 0), temp(blocks + 1) + xpath_stack_data(): result(blocks + 0, &oom), temp(blocks + 1, &oom), oom(false) { blocks[0].next = blocks[1].next = 0; blocks[0].capacity = blocks[1].capacity = sizeof(blocks[0].data); stack.result = &result; stack.temp = &temp; - - #ifdef PUGIXML_NO_EXCEPTIONS - result.error_handler = temp.error_handler = &error_handler; - #endif } ~xpath_stack_data() @@ -7492,7 +7676,7 @@ PUGI__NS_BEGIN static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc) { char_t* result = static_cast(alloc->allocate((length + 1) * sizeof(char_t))); - assert(result); + if (!result) return 0; memcpy(result, string, length * sizeof(char_t)); result[length] = 0; @@ -7521,9 +7705,13 @@ PUGI__NS_BEGIN { assert(begin <= end); - size_t length = static_cast(end - begin); + if (begin == end) + return xpath_string(); - return length == 0 ? xpath_string() : xpath_string(duplicate_string(begin, length, alloc), true, length); + size_t length = static_cast(end - begin); + const char_t* data = duplicate_string(begin, length, alloc); + + return data ? xpath_string(data, true, length) : xpath_string(); } xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false), _length_heap(0) @@ -7549,7 +7737,7 @@ PUGI__NS_BEGIN // allocate new buffer char_t* result = static_cast(alloc->reallocate(_uses_heap ? const_cast(_buffer) : 0, (target_length + 1) * sizeof(char_t), (result_length + 1) * sizeof(char_t))); - assert(result); + if (!result) return; // append first string to the new buffer in case there was no reallocation if (!_uses_heap) memcpy(result, _buffer, target_length * sizeof(char_t)); @@ -7574,15 +7762,18 @@ PUGI__NS_BEGIN { return _uses_heap ? _length_heap : strlength(_buffer); } - + char_t* data(xpath_allocator* alloc) { // make private heap copy if (!_uses_heap) { size_t length_ = strlength(_buffer); + const char_t* data_ = duplicate_string(_buffer, length_, alloc); - _buffer = duplicate_string(_buffer, length_, alloc); + if (!data_) return 0; + + _buffer = data_; _uses_heap = true; _length_heap = length_; } @@ -7664,14 +7855,18 @@ PUGI__NS_BEGIN case node_comment: case node_pi: return xpath_string::from_const(n.value()); - + case node_document: case node_element: { xpath_string result; + // element nodes can have value if parse_embed_pcdata was used + if (n.value()[0]) + result.append(xpath_string::from_const(n.value()), alloc); + xml_node cur = n.first_child(); - + while (cur && cur != n) { if (cur.type() == node_pcdata || cur.type() == node_cdata) @@ -7689,16 +7884,16 @@ PUGI__NS_BEGIN if (cur != n) cur = cur.next_sibling(); } } - + return result; } - + default: return xpath_string(); } } } - + PUGI__FN bool node_is_before_sibling(xml_node_struct* ln, xml_node_struct* rn) { assert(ln->parent == rn->parent); @@ -7722,7 +7917,7 @@ PUGI__NS_BEGIN // if rn sibling chain ended ln must be before rn return !rs; } - + PUGI__FN bool node_is_before(xml_node_struct* ln, xml_node_struct* rn) { // find common ancestor at the same depth, if any @@ -7803,7 +7998,7 @@ PUGI__NS_BEGIN return 0; } - + struct document_order_comparator { bool operator()(const xpath_node& lhs, const xpath_node& rhs) const @@ -7827,10 +8022,10 @@ PUGI__NS_BEGIN for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute()) if (a == rhs.attribute()) return true; - + return false; } - + // compare attribute parents ln = lhs.parent(); rn = rhs.parent(); @@ -7839,21 +8034,21 @@ PUGI__NS_BEGIN { // attributes go after the parent element if (lhs.parent() == rhs.node()) return false; - + ln = lhs.parent(); } else if (rhs.attribute()) { // attributes go after the parent element if (rhs.parent() == lhs.node()) return true; - + rn = rhs.parent(); } if (ln == rn) return false; if (!ln || !rn) return ln < rn; - + return node_is_before(ln.internal_object(), rn.internal_object()); } }; @@ -7866,20 +8061,22 @@ PUGI__NS_BEGIN else return rhs.attribute() ? false : lhs.node() < rhs.node(); } }; - + PUGI__FN double gen_nan() { #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) - union { float f; uint32_t i; } u[sizeof(float) == sizeof(uint32_t) ? 1 : -1]; - u[0].i = 0x7fc00000; - return u[0].f; + PUGI__STATIC_ASSERT(sizeof(float) == sizeof(uint32_t)); + typedef uint32_t UI; // BCC5 workaround + union { float f; UI i; } u; + u.i = 0x7fc00000; + return u.f; #else // fallback const volatile double zero = 0.0; return zero / zero; #endif } - + PUGI__FN bool is_nan(double value) { #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) @@ -7892,7 +8089,7 @@ PUGI__NS_BEGIN return v != v; #endif } - + PUGI__FN const char_t* convert_number_to_string_special(double value) { #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) @@ -7924,12 +8121,12 @@ PUGI__NS_BEGIN return 0; #endif } - + PUGI__FN bool convert_number_to_boolean(double value) { return (value != 0 && !is_nan(value)); } - + PUGI__FN void truncate_zeros(char* begin, char* end) { while (begin != end && end[-1] == '0') end--; @@ -7939,11 +8136,11 @@ PUGI__NS_BEGIN // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) - PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) + PUGI__FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent) { // get base values int sign, exponent; - _ecvt_s(buffer, buffer_size, value, DBL_DIG + 1, &exponent, &sign); + _ecvt_s(buffer, sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign); // truncate redundant zeros truncate_zeros(buffer, buffer + strlen(buffer)); @@ -7953,12 +8150,10 @@ PUGI__NS_BEGIN *out_exponent = exponent; } #else - PUGI__FN void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent) + PUGI__FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent) { // get a scientific notation value with IEEE DBL_DIG decimals - sprintf(buffer, "%.*e", DBL_DIG, value); - assert(strlen(buffer) < buffer_size); - (void)!buffer_size; + PUGI__SNPRINTF(buffer, "%.*e", DBL_DIG, value); // get the exponent (possibly negative) char* exponent_string = strchr(buffer, 'e'); @@ -7995,12 +8190,12 @@ PUGI__NS_BEGIN char* mantissa; int exponent; - convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent); + convert_number_to_mantissa_exponent(value, mantissa_buffer, &mantissa, &exponent); // allocate a buffer of suitable length for the number size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4; char_t* result = static_cast(alloc->allocate(sizeof(char_t) * result_size)); - assert(result); + if (!result) return xpath_string(); // make the number! char_t* s = result; @@ -8017,7 +8212,7 @@ PUGI__NS_BEGIN { while (exponent > 0) { - assert(*mantissa == 0 || static_cast(static_cast(*mantissa) - '0') <= 9); + assert(*mantissa == 0 || static_cast(*mantissa - '0') <= 9); *s++ = *mantissa ? *mantissa++ : '0'; exponent--; } @@ -8050,7 +8245,7 @@ PUGI__NS_BEGIN return xpath_string::from_heap_preallocated(result, s); } - + PUGI__FN bool check_string_to_number_format(const char_t* string) { // parse leading whitespace @@ -8117,7 +8312,7 @@ PUGI__NS_BEGIN return true; } - + PUGI__FN double round_nearest(double value) { return floor(value + 0.5); @@ -8129,17 +8324,17 @@ PUGI__NS_BEGIN // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0) return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); } - + PUGI__FN const char_t* qualified_name(const xpath_node& node) { return node.attribute() ? node.attribute().name() : node.node().name(); } - + PUGI__FN const char_t* local_name(const xpath_node& node) { const char_t* name = qualified_name(node); const char_t* p = find_char(name, ':'); - + return p ? p + 1 : name; } @@ -8169,39 +8364,39 @@ PUGI__NS_BEGIN PUGI__FN const char_t* namespace_uri(xml_node node) { namespace_uri_predicate pred = node.name(); - + xml_node p = node; - + while (p) { xml_attribute a = p.find_attribute(pred); - + if (a) return a.value(); - + p = p.parent(); } - + return PUGIXML_TEXT(""); } PUGI__FN const char_t* namespace_uri(xml_attribute attr, xml_node parent) { namespace_uri_predicate pred = attr.name(); - + // Default namespace does not apply to attributes if (!pred.prefix) return PUGIXML_TEXT(""); - + xml_node p = parent; - + while (p) { xml_attribute a = p.find_attribute(pred); - + if (a) return a.value(); - + p = p.parent(); } - + return PUGIXML_TEXT(""); } @@ -8284,12 +8479,10 @@ PUGI__NS_BEGIN if (!table[i]) table[i] = static_cast(i); - void* result = alloc->allocate_nothrow(sizeof(table)); + void* result = alloc->allocate(sizeof(table)); + if (!result) return 0; - if (result) - { - memcpy(result, table, sizeof(table)); - } + memcpy(result, table, sizeof(table)); return static_cast(result); } @@ -8376,7 +8569,7 @@ PUGI__NS_BEGIN static const xpath_node_set dummy_node_set; - PUGI__FN unsigned int hash_string(const char_t* str) + PUGI__FN PUGI__UNSIGNED_OVERFLOW unsigned int hash_string(const char_t* str) { // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time) unsigned int result = 0; @@ -8387,11 +8580,11 @@ PUGI__NS_BEGIN result += result << 10; result ^= result >> 6; } - + result += result << 3; result ^= result >> 11; result += result << 15; - + return result; } @@ -8459,7 +8652,7 @@ PUGI__NS_BEGIN break; default: - assert(!"Invalid variable type"); + assert(false && "Invalid variable type"); // unreachable } } @@ -8480,7 +8673,7 @@ PUGI__NS_BEGIN return lhs->set(static_cast(rhs)->value); default: - assert(!"Invalid variable type"); + assert(false && "Invalid variable type"); // unreachable return false; } } @@ -8545,9 +8738,9 @@ PUGI__NS_BEGIN else type = sorted; } - + if (type != order) reverse(begin, end); - + return order; } @@ -8567,7 +8760,7 @@ PUGI__NS_BEGIN return *min_element(begin, end, document_order_comparator()); default: - assert(!"Invalid node set type"); + assert(false && "Invalid node set type"); // unreachable return xpath_node(); } } @@ -8632,7 +8825,7 @@ PUGI__NS_BEGIN { // reallocate the old array or allocate a new one xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size_ + count) * sizeof(xpath_node))); - assert(data); + if (!data) return; // finalize _begin = data; @@ -8660,7 +8853,7 @@ PUGI__NS_BEGIN { if (_type == xpath_node_set::type_unsorted) sort(_begin, _end, duplicate_comparator()); - + _end = unique(_begin, _end); } @@ -8684,7 +8877,7 @@ PUGI__NS_BEGIN // reallocate the old array or allocate a new one xpath_node* data = static_cast(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node))); - assert(data); + if (!data) return; // finalize _begin = data; @@ -8768,12 +8961,12 @@ PUGI__NS_BEGIN { next(); } - + const char_t* state() const { return _cur; } - + void next() { const char_t* cur = _cur; @@ -8788,7 +8981,7 @@ PUGI__NS_BEGIN case 0: _cur_lexeme = lex_eof; break; - + case '>': if (*(cur+1) == '=') { @@ -8832,7 +9025,7 @@ PUGI__NS_BEGIN _cur_lexeme = lex_equal; break; - + case '+': cur += 1; _cur_lexeme = lex_plus; @@ -8856,7 +9049,7 @@ PUGI__NS_BEGIN _cur_lexeme = lex_union; break; - + case '$': cur += 1; @@ -8874,7 +9067,7 @@ PUGI__NS_BEGIN } _cur_lexeme_contents.end = cur; - + _cur_lexeme = lex_var_ref; } else @@ -8895,7 +9088,7 @@ PUGI__NS_BEGIN _cur_lexeme = lex_close_brace; break; - + case '[': cur += 1; _cur_lexeme = lex_open_square_brace; @@ -8926,7 +9119,7 @@ PUGI__NS_BEGIN _cur_lexeme = lex_slash; } break; - + case '.': if (*(cur+1) == '.') { @@ -8942,7 +9135,7 @@ PUGI__NS_BEGIN while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; _cur_lexeme_contents.end = cur; - + _cur_lexeme = lex_number; } else @@ -8968,7 +9161,7 @@ PUGI__NS_BEGIN _cur_lexeme_contents.begin = cur; while (*cur && *cur != terminator) cur++; _cur_lexeme_contents.end = cur; - + if (!*cur) _cur_lexeme = lex_none; else @@ -8998,7 +9191,7 @@ PUGI__NS_BEGIN _cur_lexeme_contents.begin = cur; while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; - + if (*cur == '.') { cur++; @@ -9031,7 +9224,7 @@ PUGI__NS_BEGIN } _cur_lexeme_contents.end = cur; - + _cur_lexeme = lex_string; } else @@ -9142,7 +9335,7 @@ PUGI__NS_BEGIN axis_preceding_sibling, axis_self }; - + enum nodetest_t { nodetest_none, @@ -9177,7 +9370,7 @@ PUGI__NS_BEGIN }; template const axis_t axis_to_type::axis = N; - + class xpath_ast_node { private: @@ -9297,7 +9490,7 @@ PUGI__NS_BEGIN } } - assert(!"Wrong types"); + assert(false && "Wrong types"); // unreachable return false; } @@ -9372,7 +9565,7 @@ PUGI__NS_BEGIN } else { - assert(!"Wrong types"); + assert(false && "Wrong types"); // unreachable return false; } } @@ -9496,7 +9689,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_type_node: case nodetest_all: if (is_xpath_attribute(name)) @@ -9505,7 +9698,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_all_in_namespace: if (starts_with(name, _data.nodetest) && is_xpath_attribute(name)) { @@ -9513,14 +9706,14 @@ PUGI__NS_BEGIN return true; } break; - + default: ; } return false; } - + bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc) { assert(n); @@ -9536,11 +9729,11 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_type_node: ns.push_back(xml_node(n), alloc); return true; - + case nodetest_type_comment: if (type == node_comment) { @@ -9548,7 +9741,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_type_text: if (type == node_pcdata || type == node_cdata) { @@ -9556,7 +9749,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_type_pi: if (type == node_pi) { @@ -9564,7 +9757,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_pi: if (type == node_pi && n->name && strequal(n->name, _data.nodetest)) { @@ -9572,7 +9765,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_all: if (type == node_element) { @@ -9580,7 +9773,7 @@ PUGI__NS_BEGIN return true; } break; - + case nodetest_all_in_namespace: if (type == node_element && n->name && starts_with(n->name, _data.nodetest)) { @@ -9590,7 +9783,7 @@ PUGI__NS_BEGIN break; default: - assert(!"Unknown axis"); + assert(false && "Unknown axis"); // unreachable } return false; @@ -9607,33 +9800,33 @@ PUGI__NS_BEGIN for (xml_attribute_struct* a = n->first_attribute; a; a = a->next_attribute) if (step_push(ns, a, n, alloc) & once) return; - + break; } - + case axis_child: { for (xml_node_struct* c = n->first_child; c; c = c->next_sibling) if (step_push(ns, c, alloc) & once) return; - + break; } - + case axis_descendant: case axis_descendant_or_self: { if (axis == axis_descendant_or_self) if (step_push(ns, n, alloc) & once) return; - + xml_node_struct* cur = n->first_child; - + while (cur) { if (step_push(ns, cur, alloc) & once) return; - + if (cur->first_child) cur = cur->first_child; else @@ -9644,32 +9837,32 @@ PUGI__NS_BEGIN if (cur == n) return; } - + cur = cur->next_sibling; } } - + break; } - + case axis_following_sibling: { for (xml_node_struct* c = n->next_sibling; c; c = c->next_sibling) if (step_push(ns, c, alloc) & once) return; - + break; } - + case axis_preceding_sibling: { for (xml_node_struct* c = n->prev_sibling_c; c->next_sibling; c = c->prev_sibling_c) if (step_push(ns, c, alloc) & once) return; - + break; } - + case axis_following: { xml_node_struct* cur = n; @@ -9748,7 +9941,7 @@ PUGI__NS_BEGIN break; } - + case axis_ancestor: case axis_ancestor_or_self: { @@ -9757,15 +9950,15 @@ PUGI__NS_BEGIN return; xml_node_struct* cur = n->parent; - + while (cur) { if (step_push(ns, cur, alloc) & once) return; - + cur = cur->parent; } - + break; } @@ -9783,12 +9976,12 @@ PUGI__NS_BEGIN break; } - + default: - assert(!"Unimplemented axis"); + assert(false && "Unimplemented axis"); // unreachable } } - + template void step_fill(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* p, xpath_allocator* alloc, bool once, T v) { const axis_t axis = T::axis; @@ -9803,15 +9996,15 @@ PUGI__NS_BEGIN return; xml_node_struct* cur = p; - + while (cur) { if (step_push(ns, cur, alloc) & once) return; - + cur = cur->parent; } - + break; } @@ -9827,7 +10020,7 @@ PUGI__NS_BEGIN case axis_following: { xml_node_struct* cur = p; - + while (cur) { if (cur->first_child) @@ -9864,9 +10057,9 @@ PUGI__NS_BEGIN step_fill(ns, p, alloc, once, v); break; } - + default: - assert(!"Unimplemented axis"); + assert(false && "Unimplemented axis"); // unreachable } } @@ -9908,7 +10101,7 @@ PUGI__NS_BEGIN // in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted); - + step_fill(ns, *it, stack.result, once, v); if (_right) apply_predicates(ns, size, stack, eval); } @@ -9926,7 +10119,7 @@ PUGI__NS_BEGIN return ns; } - + public: xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t* value): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) @@ -9941,14 +10134,14 @@ PUGI__NS_BEGIN assert(type == ast_number_constant); _data.number = value; } - + xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable* value): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0) { assert(type == ast_variable); _data.variable = value; } - + xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node* left = 0, xpath_ast_node* right = 0): _type(static_cast(type)), _rettype(static_cast(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0) { @@ -9983,25 +10176,25 @@ PUGI__NS_BEGIN { case ast_op_or: return _left->eval_boolean(c, stack) || _right->eval_boolean(c, stack); - + case ast_op_and: return _left->eval_boolean(c, stack) && _right->eval_boolean(c, stack); - + case ast_op_equal: return compare_eq(_left, _right, c, stack, equal_to()); case ast_op_not_equal: return compare_eq(_left, _right, c, stack, not_equal_to()); - + case ast_op_less: return compare_rel(_left, _right, c, stack, less()); - + case ast_op_greater: return compare_rel(_right, _left, c, stack, less()); case ast_op_less_or_equal: return compare_rel(_left, _right, c, stack, less_equal()); - + case ast_op_greater_or_equal: return compare_rel(_right, _left, c, stack, less_equal()); @@ -10027,43 +10220,43 @@ PUGI__NS_BEGIN case ast_func_boolean: return _left->eval_boolean(c, stack); - + case ast_func_not: return !_left->eval_boolean(c, stack); - + case ast_func_true: return true; - + case ast_func_false: return false; case ast_func_lang: { if (c.n.attribute()) return false; - + xpath_allocator_capture cr(stack.result); xpath_string lang = _left->eval_string(c, stack); - + for (xml_node n = c.n.node(); n; n = n.parent()) { xml_attribute a = n.attribute(PUGIXML_TEXT("xml:lang")); - + if (a) { const char_t* value = a.value(); - + // strnicmp / strncasecmp is not portable for (const char_t* lit = lang.c_str(); *lit; ++lit) { if (tolower_ascii(*lit) != tolower_ascii(*value)) return false; ++value; } - + return *value == 0 || *value == '-'; } } - + return false; } @@ -10082,25 +10275,24 @@ PUGI__NS_BEGIN if (_rettype == xpath_type_boolean) return _data.variable->get_boolean(); - - // fallthrough to type conversion } + // fallthrough default: { switch (_rettype) { case xpath_type_number: return convert_number_to_boolean(eval_number(c, stack)); - + case xpath_type_string: { xpath_allocator_capture cr(stack.result); return !eval_string(c, stack).empty(); } - - case xpath_type_node_set: + + case xpath_type_node_set: { xpath_allocator_capture cr(stack.result); @@ -10108,7 +10300,7 @@ PUGI__NS_BEGIN } default: - assert(!"Wrong expression for return type boolean"); + assert(false && "Wrong expression for return type boolean"); // unreachable return false; } } @@ -10121,7 +10313,7 @@ PUGI__NS_BEGIN { case ast_op_add: return _left->eval_number(c, stack) + _right->eval_number(c, stack); - + case ast_op_subtract: return _left->eval_number(c, stack) - _right->eval_number(c, stack); @@ -10142,7 +10334,7 @@ PUGI__NS_BEGIN case ast_func_last: return static_cast(c.size); - + case ast_func_position: return static_cast(c.position); @@ -10152,28 +10344,28 @@ PUGI__NS_BEGIN return static_cast(_left->eval_node_set(c, stack, nodeset_eval_all).size()); } - + case ast_func_string_length_0: { xpath_allocator_capture cr(stack.result); return static_cast(string_value(c.n, stack.result).length()); } - + case ast_func_string_length_1: { xpath_allocator_capture cr(stack.result); return static_cast(_left->eval_string(c, stack).length()); } - + case ast_func_number_0: { xpath_allocator_capture cr(stack.result); return convert_string_to_number(string_value(c.n, stack.result).c_str()); } - + case ast_func_number_1: return _left->eval_number(c, stack); @@ -10182,76 +10374,75 @@ PUGI__NS_BEGIN xpath_allocator_capture cr(stack.result); double r = 0; - + xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_all); - + for (const xpath_node* it = ns.begin(); it != ns.end(); ++it) { xpath_allocator_capture cri(stack.result); r += convert_string_to_number(string_value(*it, stack.result).c_str()); } - + return r; } case ast_func_floor: { double r = _left->eval_number(c, stack); - + return r == r ? floor(r) : r; } case ast_func_ceiling: { double r = _left->eval_number(c, stack); - + return r == r ? ceil(r) : r; } case ast_func_round: return round_nearest_nzero(_left->eval_number(c, stack)); - + case ast_variable: { assert(_rettype == _data.variable->type()); if (_rettype == xpath_type_number) return _data.variable->get_number(); - - // fallthrough to type conversion } + // fallthrough default: { switch (_rettype) { case xpath_type_boolean: return eval_boolean(c, stack) ? 1 : 0; - + case xpath_type_string: { xpath_allocator_capture cr(stack.result); return convert_string_to_number(eval_string(c, stack).c_str()); } - + case xpath_type_node_set: { xpath_allocator_capture cr(stack.result); return convert_string_to_number(eval_string(c, stack).c_str()); } - + default: - assert(!"Wrong expression for return type number"); + assert(false && "Wrong expression for return type number"); // unreachable return 0; } - + } } } - + xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack) { assert(_type == ast_func_concat); @@ -10262,16 +10453,9 @@ PUGI__NS_BEGIN size_t count = 1; for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++; - // gather all strings - xpath_string static_buffer[4]; - xpath_string* buffer = static_buffer; - - // allocate on-heap for large concats - if (count > sizeof(static_buffer) / sizeof(static_buffer[0])) - { - buffer = static_cast(stack.temp->allocate(count * sizeof(xpath_string))); - assert(buffer); - } + // allocate a buffer for temporary string objects + xpath_string* buffer = static_cast(stack.temp->allocate(count * sizeof(xpath_string))); + if (!buffer) return xpath_string(); // evaluate all strings to temporary stack xpath_stack swapped_stack = {stack.temp, stack.result}; @@ -10288,7 +10472,7 @@ PUGI__NS_BEGIN // create final string char_t* result = static_cast(stack.result->allocate((length + 1) * sizeof(char_t))); - assert(result); + if (!result) return xpath_string(); char_t* ri = result; @@ -10307,11 +10491,11 @@ PUGI__NS_BEGIN { case ast_string_constant: return xpath_string::from_const(_data.string); - + case ast_func_local_name_0: { xpath_node na = c.n; - + return xpath_string::from_const(local_name(na)); } @@ -10321,14 +10505,14 @@ PUGI__NS_BEGIN xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); xpath_node na = ns.first(); - + return xpath_string::from_const(local_name(na)); } case ast_func_name_0: { xpath_node na = c.n; - + return xpath_string::from_const(qualified_name(na)); } @@ -10338,14 +10522,14 @@ PUGI__NS_BEGIN xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); xpath_node na = ns.first(); - + return xpath_string::from_const(qualified_name(na)); } case ast_func_namespace_uri_0: { xpath_node na = c.n; - + return xpath_string::from_const(namespace_uri(na)); } @@ -10355,7 +10539,7 @@ PUGI__NS_BEGIN xpath_node_set_raw ns = _left->eval_node_set(c, stack, nodeset_eval_first); xpath_node na = ns.first(); - + return xpath_string::from_const(namespace_uri(na)); } @@ -10378,10 +10562,10 @@ PUGI__NS_BEGIN xpath_string p = _right->eval_string(c, swapped_stack); const char_t* pos = find_substring(s.c_str(), p.c_str()); - + return pos ? xpath_string::from_heap(s.c_str(), pos, stack.result) : xpath_string(); } - + case ast_func_substring_after: { xpath_allocator_capture cr(stack.temp); @@ -10390,7 +10574,7 @@ PUGI__NS_BEGIN xpath_string s = _left->eval_string(c, swapped_stack); xpath_string p = _right->eval_string(c, swapped_stack); - + const char_t* pos = find_substring(s.c_str(), p.c_str()); if (!pos) return xpath_string(); @@ -10410,19 +10594,19 @@ PUGI__NS_BEGIN size_t s_length = s.length(); double first = round_nearest(_right->eval_number(c, stack)); - + if (is_nan(first)) return xpath_string(); // NaN else if (first >= s_length + 1) return xpath_string(); - + size_t pos = first < 1 ? 1 : static_cast(first); assert(1 <= pos && pos <= s_length + 1); const char_t* rbegin = s.c_str() + (pos - 1); const char_t* rend = s.c_str() + s.length(); - + return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin); } - + case ast_func_substring_3: { xpath_allocator_capture cr(stack.temp); @@ -10434,12 +10618,12 @@ PUGI__NS_BEGIN double first = round_nearest(_right->eval_number(c, stack)); double last = first + round_nearest(_right->_next->eval_number(c, stack)); - + if (is_nan(first) || is_nan(last)) return xpath_string(); else if (first >= s_length + 1) return xpath_string(); else if (first >= last) return xpath_string(); else if (last < 1) return xpath_string(); - + size_t pos = first < 1 ? 1 : static_cast(first); size_t end = last >= s_length + 1 ? s_length + 1 : static_cast(last); @@ -10455,6 +10639,8 @@ PUGI__NS_BEGIN xpath_string s = string_value(c.n, stack.result); char_t* begin = s.data(stack.result); + if (!begin) return xpath_string(); + char_t* end = normalize_space(begin); return xpath_string::from_heap_preallocated(begin, end); @@ -10465,8 +10651,10 @@ PUGI__NS_BEGIN xpath_string s = _left->eval_string(c, stack); char_t* begin = s.data(stack.result); + if (!begin) return xpath_string(); + char_t* end = normalize_space(begin); - + return xpath_string::from_heap_preallocated(begin, end); } @@ -10481,6 +10669,8 @@ PUGI__NS_BEGIN xpath_string to = _right->_next->eval_string(c, swapped_stack); char_t* begin = s.data(stack.result); + if (!begin) return xpath_string(); + char_t* end = translate(begin, from.c_str(), to.c_str(), to.length()); return xpath_string::from_heap_preallocated(begin, end); @@ -10491,6 +10681,8 @@ PUGI__NS_BEGIN xpath_string s = _left->eval_string(c, stack); char_t* begin = s.data(stack.result); + if (!begin) return xpath_string(); + char_t* end = translate_table(begin, _data.table); return xpath_string::from_heap_preallocated(begin, end); @@ -10502,20 +10694,19 @@ PUGI__NS_BEGIN if (_rettype == xpath_type_string) return xpath_string::from_const(_data.variable->get_string()); - - // fallthrough to type conversion } + // fallthrough default: { switch (_rettype) { case xpath_type_boolean: return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false")); - + case xpath_type_number: return convert_number_to_string(eval_number(c, stack), stack.result); - + case xpath_type_node_set: { xpath_allocator_capture cr(stack.temp); @@ -10525,9 +10716,9 @@ PUGI__NS_BEGIN xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first); return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result); } - + default: - assert(!"Wrong expression for return type string"); + assert(false && "Wrong expression for return type string"); // unreachable return xpath_string(); } } @@ -10566,20 +10757,20 @@ PUGI__NS_BEGIN bool once = eval_once(set.type(), eval); apply_predicate(set, 0, stack, once); - + return set; } - + case ast_func_id: return xpath_node_set_raw(); - + case ast_step: { switch (_axis) { case axis_ancestor: return step_do(c, stack, eval, axis_to_type()); - + case axis_ancestor_or_self: return step_do(c, stack, eval, axis_to_type()); @@ -10588,7 +10779,7 @@ PUGI__NS_BEGIN case axis_child: return step_do(c, stack, eval, axis_to_type()); - + case axis_descendant: return step_do(c, stack, eval, axis_to_type()); @@ -10597,28 +10788,28 @@ PUGI__NS_BEGIN case axis_following: return step_do(c, stack, eval, axis_to_type()); - + case axis_following_sibling: return step_do(c, stack, eval, axis_to_type()); - + case axis_namespace: // namespaced axis is not supported return xpath_node_set_raw(); - + case axis_parent: return step_do(c, stack, eval, axis_to_type()); - + case axis_preceding: return step_do(c, stack, eval, axis_to_type()); case axis_preceding_sibling: return step_do(c, stack, eval, axis_to_type()); - + case axis_self: return step_do(c, stack, eval, axis_to_type()); default: - assert(!"Unknown axis"); + assert(false && "Unknown axis"); // unreachable return xpath_node_set_raw(); } } @@ -10652,21 +10843,25 @@ PUGI__NS_BEGIN return ns; } - - // fallthrough to type conversion } + // fallthrough default: - assert(!"Wrong expression for return type node set"); + assert(false && "Wrong expression for return type node set"); // unreachable return xpath_node_set_raw(); } } void optimize(xpath_allocator* alloc) { - if (_left) _left->optimize(alloc); - if (_right) _right->optimize(alloc); - if (_next) _next->optimize(alloc); + if (_left) + _left->optimize(alloc); + + if (_right) + _right->optimize(alloc); + + if (_next) + _next->optimize(alloc); optimize_self(alloc); } @@ -10730,7 +10925,7 @@ PUGI__NS_BEGIN _type = ast_opt_compare_attribute; } } - + bool is_posinv_expr() const { switch (_type) @@ -10754,10 +10949,10 @@ PUGI__NS_BEGIN default: if (_left && !_left->is_posinv_expr()) return false; - + for (xpath_ast_node* n = _right; n; n = n->_next) if (!n->is_posinv_expr()) return false; - + return true; } } @@ -10795,65 +10990,77 @@ PUGI__NS_BEGIN char_t _scratch[32]; - #ifdef PUGIXML_NO_EXCEPTIONS - jmp_buf _error_handler; - #endif - - void throw_error(const char* message) + xpath_ast_node* error(const char* message) { _result->error = message; _result->offset = _lexer.current_pos() - _query; - #ifdef PUGIXML_NO_EXCEPTIONS - longjmp(_error_handler, 1); - #else - throw xpath_exception(*_result); - #endif + return 0; } - void throw_error_oom() + xpath_ast_node* error_oom() { - #ifdef PUGIXML_NO_EXCEPTIONS - throw_error("Out of memory"); - #else - throw std::bad_alloc(); - #endif + assert(_alloc->_error); + *_alloc->_error = true; + + return 0; } void* alloc_node() { - void* result = _alloc->allocate_nothrow(sizeof(xpath_ast_node)); + return _alloc->allocate(sizeof(xpath_ast_node)); + } - if (!result) throw_error_oom(); + xpath_ast_node* alloc_node(ast_type_t type, xpath_value_type rettype, const char_t* value) + { + void* memory = alloc_node(); + return memory ? new (memory) xpath_ast_node(type, rettype, value) : 0; + } - return result; + xpath_ast_node* alloc_node(ast_type_t type, xpath_value_type rettype, double value) + { + void* memory = alloc_node(); + return memory ? new (memory) xpath_ast_node(type, rettype, value) : 0; + } + + xpath_ast_node* alloc_node(ast_type_t type, xpath_value_type rettype, xpath_variable* value) + { + void* memory = alloc_node(); + return memory ? new (memory) xpath_ast_node(type, rettype, value) : 0; + } + + xpath_ast_node* alloc_node(ast_type_t type, xpath_value_type rettype, xpath_ast_node* left = 0, xpath_ast_node* right = 0) + { + void* memory = alloc_node(); + return memory ? new (memory) xpath_ast_node(type, rettype, left, right) : 0; + } + + xpath_ast_node* alloc_node(ast_type_t type, xpath_ast_node* left, axis_t axis, nodetest_t test, const char_t* contents) + { + void* memory = alloc_node(); + return memory ? new (memory) xpath_ast_node(type, left, axis, test, contents) : 0; + } + + xpath_ast_node* alloc_node(ast_type_t type, xpath_ast_node* left, xpath_ast_node* right, predicate_t test) + { + void* memory = alloc_node(); + return memory ? new (memory) xpath_ast_node(type, left, right, test) : 0; } const char_t* alloc_string(const xpath_lexer_string& value) { - if (value.begin) - { - size_t length = static_cast(value.end - value.begin); + if (!value.begin) + return PUGIXML_TEXT(""); - char_t* c = static_cast(_alloc->allocate_nothrow((length + 1) * sizeof(char_t))); - if (!c) throw_error_oom(); - assert(c); // workaround for clang static analysis + size_t length = static_cast(value.end - value.begin); - memcpy(c, value.begin, length * sizeof(char_t)); - c[length] = 0; + char_t* c = static_cast(_alloc->allocate((length + 1) * sizeof(char_t))); + if (!c) return 0; - return c; - } - else return 0; - } + memcpy(c, value.begin, length * sizeof(char_t)); + c[length] = 0; - xpath_ast_node* parse_function_helper(ast_type_t type0, ast_type_t type1, size_t argc, xpath_ast_node* args[2]) - { - assert(argc <= 1); - - if (argc == 1 && args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - - return new (alloc_node()) xpath_ast_node(argc == 0 ? type0 : type1, xpath_type_string, args[0]); + return c; } xpath_ast_node* parse_function(const xpath_lexer_string& name, size_t argc, xpath_ast_node* args[2]) @@ -10862,111 +11069,118 @@ PUGI__NS_BEGIN { case 'b': if (name == PUGIXML_TEXT("boolean") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_boolean, xpath_type_boolean, args[0]); - + return alloc_node(ast_func_boolean, xpath_type_boolean, args[0]); + break; - + case 'c': if (name == PUGIXML_TEXT("count") && argc == 1) { - if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - return new (alloc_node()) xpath_ast_node(ast_func_count, xpath_type_number, args[0]); + if (args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set"); + return alloc_node(ast_func_count, xpath_type_number, args[0]); } else if (name == PUGIXML_TEXT("contains") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_boolean, args[0], args[1]); + return alloc_node(ast_func_contains, xpath_type_boolean, args[0], args[1]); else if (name == PUGIXML_TEXT("concat") && argc >= 2) - return new (alloc_node()) xpath_ast_node(ast_func_concat, xpath_type_string, args[0], args[1]); + return alloc_node(ast_func_concat, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("ceiling") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_ceiling, xpath_type_number, args[0]); - - break; - - case 'f': - if (name == PUGIXML_TEXT("false") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_false, xpath_type_boolean); - else if (name == PUGIXML_TEXT("floor") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_floor, xpath_type_number, args[0]); - - break; - - case 'i': - if (name == PUGIXML_TEXT("id") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_id, xpath_type_node_set, args[0]); - - break; - - case 'l': - if (name == PUGIXML_TEXT("last") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_last, xpath_type_number); - else if (name == PUGIXML_TEXT("lang") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_lang, xpath_type_boolean, args[0]); - else if (name == PUGIXML_TEXT("local-name") && argc <= 1) - return parse_function_helper(ast_func_local_name_0, ast_func_local_name_1, argc, args); - - break; - - case 'n': - if (name == PUGIXML_TEXT("name") && argc <= 1) - return parse_function_helper(ast_func_name_0, ast_func_name_1, argc, args); - else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1) - return parse_function_helper(ast_func_namespace_uri_0, ast_func_namespace_uri_1, argc, args); - else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("not") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_not, xpath_type_boolean, args[0]); - else if (name == PUGIXML_TEXT("number") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]); - - break; - - case 'p': - if (name == PUGIXML_TEXT("position") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_position, xpath_type_number); - - break; - - case 'r': - if (name == PUGIXML_TEXT("round") && argc == 1) - return new (alloc_node()) xpath_ast_node(ast_func_round, xpath_type_number, args[0]); + return alloc_node(ast_func_ceiling, xpath_type_number, args[0]); break; - - case 's': - if (name == PUGIXML_TEXT("string") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]); - else if (name == PUGIXML_TEXT("string-length") && argc <= 1) - return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_number, args[0]); - else if (name == PUGIXML_TEXT("starts-with") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring-before") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_substring_before, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring-after") && argc == 2) - return new (alloc_node()) xpath_ast_node(ast_func_substring_after, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3)) - return new (alloc_node()) xpath_ast_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]); - else if (name == PUGIXML_TEXT("sum") && argc == 1) + + case 'f': + if (name == PUGIXML_TEXT("false") && argc == 0) + return alloc_node(ast_func_false, xpath_type_boolean); + else if (name == PUGIXML_TEXT("floor") && argc == 1) + return alloc_node(ast_func_floor, xpath_type_number, args[0]); + + break; + + case 'i': + if (name == PUGIXML_TEXT("id") && argc == 1) + return alloc_node(ast_func_id, xpath_type_node_set, args[0]); + + break; + + case 'l': + if (name == PUGIXML_TEXT("last") && argc == 0) + return alloc_node(ast_func_last, xpath_type_number); + else if (name == PUGIXML_TEXT("lang") && argc == 1) + return alloc_node(ast_func_lang, xpath_type_boolean, args[0]); + else if (name == PUGIXML_TEXT("local-name") && argc <= 1) { - if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set"); - return new (alloc_node()) xpath_ast_node(ast_func_sum, xpath_type_number, args[0]); + if (argc == 1 && args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set"); + return alloc_node(argc == 0 ? ast_func_local_name_0 : ast_func_local_name_1, xpath_type_string, args[0]); } break; - + + case 'n': + if (name == PUGIXML_TEXT("name") && argc <= 1) + { + if (argc == 1 && args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set"); + return alloc_node(argc == 0 ? ast_func_name_0 : ast_func_name_1, xpath_type_string, args[0]); + } + else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1) + { + if (argc == 1 && args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set"); + return alloc_node(argc == 0 ? ast_func_namespace_uri_0 : ast_func_namespace_uri_1, xpath_type_string, args[0]); + } + else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1) + return alloc_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]); + else if (name == PUGIXML_TEXT("not") && argc == 1) + return alloc_node(ast_func_not, xpath_type_boolean, args[0]); + else if (name == PUGIXML_TEXT("number") && argc <= 1) + return alloc_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]); + + break; + + case 'p': + if (name == PUGIXML_TEXT("position") && argc == 0) + return alloc_node(ast_func_position, xpath_type_number); + + break; + + case 'r': + if (name == PUGIXML_TEXT("round") && argc == 1) + return alloc_node(ast_func_round, xpath_type_number, args[0]); + + break; + + case 's': + if (name == PUGIXML_TEXT("string") && argc <= 1) + return alloc_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]); + else if (name == PUGIXML_TEXT("string-length") && argc <= 1) + return alloc_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_number, args[0]); + else if (name == PUGIXML_TEXT("starts-with") && argc == 2) + return alloc_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]); + else if (name == PUGIXML_TEXT("substring-before") && argc == 2) + return alloc_node(ast_func_substring_before, xpath_type_string, args[0], args[1]); + else if (name == PUGIXML_TEXT("substring-after") && argc == 2) + return alloc_node(ast_func_substring_after, xpath_type_string, args[0], args[1]); + else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3)) + return alloc_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]); + else if (name == PUGIXML_TEXT("sum") && argc == 1) + { + if (args[0]->rettype() != xpath_type_node_set) return error("Function has to be applied to node set"); + return alloc_node(ast_func_sum, xpath_type_number, args[0]); + } + + break; + case 't': if (name == PUGIXML_TEXT("translate") && argc == 3) - return new (alloc_node()) xpath_ast_node(ast_func_translate, xpath_type_string, args[0], args[1]); + return alloc_node(ast_func_translate, xpath_type_string, args[0], args[1]); else if (name == PUGIXML_TEXT("true") && argc == 0) - return new (alloc_node()) xpath_ast_node(ast_func_true, xpath_type_boolean); - + return alloc_node(ast_func_true, xpath_type_boolean); + break; default: break; } - throw_error("Unrecognized function or wrong parameter count"); - - return 0; + return error("Unrecognized function or wrong parameter count"); } axis_t parse_axis_name(const xpath_lexer_string& name, bool& specified) @@ -10982,37 +11196,37 @@ PUGI__NS_BEGIN return axis_ancestor_or_self; else if (name == PUGIXML_TEXT("attribute")) return axis_attribute; - + break; - + case 'c': if (name == PUGIXML_TEXT("child")) return axis_child; - + break; - + case 'd': if (name == PUGIXML_TEXT("descendant")) return axis_descendant; else if (name == PUGIXML_TEXT("descendant-or-self")) return axis_descendant_or_self; - + break; - + case 'f': if (name == PUGIXML_TEXT("following")) return axis_following; else if (name == PUGIXML_TEXT("following-sibling")) return axis_following_sibling; - + break; - + case 'n': if (name == PUGIXML_TEXT("namespace")) return axis_namespace; - + break; - + case 'p': if (name == PUGIXML_TEXT("parent")) return axis_parent; @@ -11020,13 +11234,13 @@ PUGI__NS_BEGIN return axis_preceding; else if (name == PUGIXML_TEXT("preceding-sibling")) return axis_preceding_sibling; - + break; - + case 's': if (name == PUGIXML_TEXT("self")) return axis_self; - + break; default: @@ -11064,7 +11278,7 @@ PUGI__NS_BEGIN return nodetest_type_text; break; - + default: break; } @@ -11082,18 +11296,18 @@ PUGI__NS_BEGIN xpath_lexer_string name = _lexer.contents(); if (!_variables) - throw_error("Unknown variable: variable set is not provided"); + return error("Unknown variable: variable set is not provided"); xpath_variable* var = 0; if (!get_variable_scratch(_scratch, _variables, name.begin, name.end, &var)) - throw_error_oom(); + return error_oom(); if (!var) - throw_error("Unknown variable: variable set does not contain the given name"); + return error("Unknown variable: variable set does not contain the given name"); _lexer.next(); - return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var); + return alloc_node(ast_variable, var->type(), var); } case lex_open_brace: @@ -11101,9 +11315,10 @@ PUGI__NS_BEGIN _lexer.next(); xpath_ast_node* n = parse_expression(); + if (!n) return 0; if (_lexer.current() != lex_close_brace) - throw_error("Unmatched braces"); + return error("Expected ')' to match an opening '('"); _lexer.next(); @@ -11113,11 +11328,11 @@ PUGI__NS_BEGIN case lex_quoted_string: { const char_t* value = alloc_string(_lexer.contents()); + if (!value) return 0; - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_string_constant, xpath_type_string, value); _lexer.next(); - return n; + return alloc_node(ast_string_constant, xpath_type_string, value); } case lex_number: @@ -11125,84 +11340,86 @@ PUGI__NS_BEGIN double value = 0; if (!convert_string_to_number_scratch(_scratch, _lexer.contents().begin, _lexer.contents().end, &value)) - throw_error_oom(); + return error_oom(); - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value); _lexer.next(); - return n; + return alloc_node(ast_number_constant, xpath_type_number, value); } case lex_string: { xpath_ast_node* args[2] = {0}; size_t argc = 0; - + xpath_lexer_string function = _lexer.contents(); _lexer.next(); - - xpath_ast_node* last_arg = 0; - - if (_lexer.current() != lex_open_brace) - throw_error("Unrecognized function call"); - _lexer.next(); - if (_lexer.current() != lex_close_brace) - args[argc++] = parse_expression(); + xpath_ast_node* last_arg = 0; + + if (_lexer.current() != lex_open_brace) + return error("Unrecognized function call"); + _lexer.next(); while (_lexer.current() != lex_close_brace) { - if (_lexer.current() != lex_comma) - throw_error("No comma between function arguments"); - _lexer.next(); - + if (argc > 0) + { + if (_lexer.current() != lex_comma) + return error("No comma between function arguments"); + _lexer.next(); + } + xpath_ast_node* n = parse_expression(); - + if (!n) return 0; + if (argc < 2) args[argc] = n; else last_arg->set_next(n); argc++; last_arg = n; } - + _lexer.next(); return parse_function(function, argc, args); } default: - throw_error("Unrecognizable primary expression"); - - return 0; + return error("Unrecognizable primary expression"); } } - + // FilterExpr ::= PrimaryExpr | FilterExpr Predicate // Predicate ::= '[' PredicateExpr ']' // PredicateExpr ::= Expr xpath_ast_node* parse_filter_expression() { xpath_ast_node* n = parse_primary_expression(); + if (!n) return 0; while (_lexer.current() == lex_open_square_brace) { _lexer.next(); + if (n->rettype() != xpath_type_node_set) + return error("Predicate has to be applied to node set"); + xpath_ast_node* expr = parse_expression(); + if (!expr) return 0; - if (n->rettype() != xpath_type_node_set) throw_error("Predicate has to be applied to node set"); - - n = new (alloc_node()) xpath_ast_node(ast_filter, n, expr, predicate_default); + n = alloc_node(ast_filter, n, expr, predicate_default); + if (!n) return 0; if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); - + return error("Expected ']' to match an opening '['"); + _lexer.next(); } - + return n; } - + // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep // AxisSpecifier ::= AxisName '::' | '@'? // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' @@ -11211,7 +11428,7 @@ PUGI__NS_BEGIN xpath_ast_node* parse_step(xpath_ast_node* set) { if (set && set->rettype() != xpath_type_node_set) - throw_error("Step has to be applied to node set"); + return error("Step has to be applied to node set"); bool axis_specified = false; axis_t axis = axis_child; // implied child axis @@ -11220,25 +11437,31 @@ PUGI__NS_BEGIN { axis = axis_attribute; axis_specified = true; - + _lexer.next(); } else if (_lexer.current() == lex_dot) { _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0); + + if (_lexer.current() == lex_open_square_brace) + return error("Predicates are not allowed after an abbreviated step"); + + return alloc_node(ast_step, set, axis_self, nodetest_type_node, 0); } else if (_lexer.current() == lex_double_dot) { _lexer.next(); - - return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0); + + if (_lexer.current() == lex_open_square_brace) + return error("Predicates are not allowed after an abbreviated step"); + + return alloc_node(ast_step, set, axis_parent, nodetest_type_node, 0); } - + nodetest_t nt_type = nodetest_none; xpath_lexer_string nt_name; - + if (_lexer.current() == lex_string) { // node name test @@ -11249,11 +11472,13 @@ PUGI__NS_BEGIN if (_lexer.current() == lex_double_colon) { // parse axis name - if (axis_specified) throw_error("Two axis specifiers in one step"); + if (axis_specified) + return error("Two axis specifiers in one step"); axis = parse_axis_name(nt_name, axis_specified); - if (!axis_specified) throw_error("Unknown axis"); + if (!axis_specified) + return error("Unknown axis"); // read actual node test _lexer.next(); @@ -11269,42 +11494,47 @@ PUGI__NS_BEGIN nt_name = _lexer.contents(); _lexer.next(); } - else throw_error("Unrecognized node test"); + else + { + return error("Unrecognized node test"); + } } - + if (nt_type == nodetest_none) { // node type test or processing-instruction if (_lexer.current() == lex_open_brace) { _lexer.next(); - + if (_lexer.current() == lex_close_brace) { _lexer.next(); nt_type = parse_node_test_type(nt_name); - if (nt_type == nodetest_none) throw_error("Unrecognized node type"); - + if (nt_type == nodetest_none) + return error("Unrecognized node type"); + nt_name = xpath_lexer_string(); } else if (nt_name == PUGIXML_TEXT("processing-instruction")) { if (_lexer.current() != lex_quoted_string) - throw_error("Only literals are allowed as arguments to processing-instruction()"); - + return error("Only literals are allowed as arguments to processing-instruction()"); + nt_type = nodetest_pi; nt_name = _lexer.contents(); _lexer.next(); - + if (_lexer.current() != lex_close_brace) - throw_error("Unmatched brace near processing-instruction()"); + return error("Unmatched brace near processing-instruction()"); _lexer.next(); } else - throw_error("Unmatched brace near node type test"); - + { + return error("Unmatched brace near node type test"); + } } // QName or NCName:* else @@ -11312,10 +11542,13 @@ PUGI__NS_BEGIN if (nt_name.end - nt_name.begin > 2 && nt_name.end[-2] == ':' && nt_name.end[-1] == '*') // NCName:* { nt_name.end--; // erase * - + nt_type = nodetest_all_in_namespace; } - else nt_type = nodetest_name; + else + { + nt_type = nodetest_name; + } } } } @@ -11324,52 +11557,66 @@ PUGI__NS_BEGIN nt_type = nodetest_all; _lexer.next(); } - else throw_error("Unrecognized node test"); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step, set, axis, nt_type, alloc_string(nt_name)); - + else + { + return error("Unrecognized node test"); + } + + const char_t* nt_name_copy = alloc_string(nt_name); + if (!nt_name_copy) return 0; + + xpath_ast_node* n = alloc_node(ast_step, set, axis, nt_type, nt_name_copy); + if (!n) return 0; + xpath_ast_node* last = 0; - + while (_lexer.current() == lex_open_square_brace) { _lexer.next(); - - xpath_ast_node* expr = parse_expression(); - xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, 0, expr, predicate_default); - + xpath_ast_node* expr = parse_expression(); + if (!expr) return 0; + + xpath_ast_node* pred = alloc_node(ast_predicate, 0, expr, predicate_default); + if (!pred) return 0; + if (_lexer.current() != lex_close_square_brace) - throw_error("Unmatched square brace"); + return error("Expected ']' to match an opening '['"); _lexer.next(); - + if (last) last->set_next(pred); else n->set_right(pred); - + last = pred; } return n; } - + // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step xpath_ast_node* parse_relative_location_path(xpath_ast_node* set) { xpath_ast_node* n = parse_step(set); - + if (!n) return 0; + while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) { lexeme_t l = _lexer.current(); _lexer.next(); if (l == lex_double_slash) - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - + { + n = alloc_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); + if (!n) return 0; + } + n = parse_step(n); + if (!n) return 0; } - + return n; } - + // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath xpath_ast_node* parse_location_path() @@ -11377,8 +11624,9 @@ PUGI__NS_BEGIN if (_lexer.current() == lex_slash) { _lexer.next(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); + + xpath_ast_node* n = alloc_node(ast_step_root, xpath_type_node_set); + if (!n) return 0; // relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path lexeme_t l = _lexer.current(); @@ -11391,17 +11639,20 @@ PUGI__NS_BEGIN else if (_lexer.current() == lex_double_slash) { _lexer.next(); - - xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set); - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); - + + xpath_ast_node* n = alloc_node(ast_step_root, xpath_type_node_set); + if (!n) return 0; + + n = alloc_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); + if (!n) return 0; + return parse_relative_location_path(n); } // else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1 return parse_relative_location_path(0); } - + // PathExpr ::= LocationPath // | FilterExpr // | FilterExpr '/' RelativeLocationPath @@ -11416,8 +11667,7 @@ PUGI__NS_BEGIN // PrimaryExpr begins with '$' in case of it being a variable reference, // '(' in case of it being an expression, string literal, number constant or // function call. - - if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || + if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || _lexer.current() == lex_quoted_string || _lexer.current() == lex_number || _lexer.current() == lex_string) { @@ -11425,29 +11675,34 @@ PUGI__NS_BEGIN { // This is either a function call, or not - if not, we shall proceed with location path const char_t* state = _lexer.state(); - + while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state; - - if (*state != '(') return parse_location_path(); + + if (*state != '(') + return parse_location_path(); // This looks like a function call; however this still can be a node-test. Check it. - if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path(); + if (parse_node_test_type(_lexer.contents()) != nodetest_none) + return parse_location_path(); } - + xpath_ast_node* n = parse_filter_expression(); + if (!n) return 0; if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash) { lexeme_t l = _lexer.current(); _lexer.next(); - + if (l == lex_double_slash) { - if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set"); + if (n->rettype() != xpath_type_node_set) + return error("Step has to be applied to node set"); - n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); + n = alloc_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0); + if (!n) return 0; } - + // select from location path return parse_relative_location_path(n); } @@ -11459,12 +11714,15 @@ PUGI__NS_BEGIN _lexer.next(); // precedence 7+ - only parses union expressions - xpath_ast_node* expr = parse_expression_rec(parse_path_or_unary_expression(), 7); + xpath_ast_node* n = parse_expression(7); + if (!n) return 0; - return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr); + return alloc_node(ast_op_negate, xpath_type_number, n); } else + { return parse_location_path(); + } } struct binary_op_t @@ -11542,20 +11800,23 @@ PUGI__NS_BEGIN _lexer.next(); xpath_ast_node* rhs = parse_path_or_unary_expression(); + if (!rhs) return 0; binary_op_t nextop = binary_op_t::parse(_lexer); while (nextop.asttype != ast_unknown && nextop.precedence > op.precedence) { rhs = parse_expression_rec(rhs, nextop.precedence); + if (!rhs) return 0; nextop = binary_op_t::parse(_lexer); } if (op.asttype == ast_op_union && (lhs->rettype() != xpath_type_node_set || rhs->rettype() != xpath_type_node_set)) - throw_error("Union operator has to be applied to node sets"); + return error("Union operator has to be applied to node sets"); - lhs = new (alloc_node()) xpath_ast_node(op.asttype, op.rettype, lhs, rhs); + lhs = alloc_node(op.asttype, op.rettype, lhs, rhs); + if (!lhs) return 0; op = binary_op_t::parse(_lexer); } @@ -11581,9 +11842,12 @@ PUGI__NS_BEGIN // | MultiplicativeExpr '*' UnaryExpr // | MultiplicativeExpr 'div' UnaryExpr // | MultiplicativeExpr 'mod' UnaryExpr - xpath_ast_node* parse_expression() + xpath_ast_node* parse_expression(int limit = 0) { - return parse_expression_rec(parse_path_or_unary_expression(), 0); + xpath_ast_node* n = parse_path_or_unary_expression(); + if (!n) return 0; + + return parse_expression_rec(n, limit); } xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result) @@ -11592,28 +11856,21 @@ PUGI__NS_BEGIN xpath_ast_node* parse() { - xpath_ast_node* result = parse_expression(); - + xpath_ast_node* n = parse_expression(); + if (!n) return 0; + + // check if there are unparsed tokens left if (_lexer.current() != lex_eof) - { - // there are still unparsed tokens left, error - throw_error("Incorrect query"); - } - - return result; + return error("Incorrect query"); + + return n; } static xpath_ast_node* parse(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result) { xpath_parser parser(query, variables, alloc, result); - #ifdef PUGIXML_NO_EXCEPTIONS - int error = setjmp(parser._error_handler); - - return (error == 0) ? parser.parse() : 0; - #else return parser.parse(); - #endif } }; @@ -11636,7 +11893,7 @@ PUGI__NS_BEGIN xml_memory::deallocate(impl); } - xpath_query_impl(): root(0), alloc(&block) + xpath_query_impl(): root(0), alloc(&block, &oom), oom(false) { block.next = 0; block.capacity = sizeof(block.data); @@ -11645,21 +11902,9 @@ PUGI__NS_BEGIN xpath_ast_node* root; xpath_allocator alloc; xpath_memory_block block; + bool oom; }; - PUGI__FN xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd) - { - if (!impl) return xpath_string(); - - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_string(); - #endif - - xpath_context c(n, 1, 1); - - return impl->root->eval_string(c, sd.stack); - } - PUGI__FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl) { if (!impl) return 0; @@ -11687,7 +11932,7 @@ namespace pugi { assert(_result.error); } - + PUGI__FN const char* xpath_exception::what() const throw() { return _result.error; @@ -11698,15 +11943,15 @@ namespace pugi return _result; } #endif - + PUGI__FN xpath_node::xpath_node() { } - + PUGI__FN xpath_node::xpath_node(const xml_node& node_): _node(node_) { } - + PUGI__FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_) { } @@ -11715,12 +11960,12 @@ namespace pugi { return _attribute ? xml_node() : _node; } - + PUGI__FN xml_attribute xpath_node::attribute() const { return _attribute; } - + PUGI__FN xml_node xpath_node::parent() const { return _attribute ? _node : _node.parent(); @@ -11734,7 +11979,7 @@ namespace pugi { return (_node || _attribute) ? unspecified_bool_xpath_node : 0; } - + PUGI__FN bool xpath_node::operator!() const { return !(_node || _attribute); @@ -11744,7 +11989,7 @@ namespace pugi { return _node == n._node && _attribute == n._attribute; } - + PUGI__FN bool xpath_node::operator!=(const xpath_node& n) const { return _node != n._node || _attribute != n._attribute; @@ -11795,7 +12040,7 @@ namespace pugi } memcpy(storage, begin_, size_ * sizeof(xpath_node)); - + // deallocate old buffer if (_begin != &_storage) impl::xml_memory::deallocate(_begin); @@ -11806,8 +12051,8 @@ namespace pugi } } -#if __cplusplus >= 201103 - PUGI__FN void xpath_node_set::_move(xpath_node_set& rhs) +#ifdef PUGIXML_HAS_MOVE + PUGI__FN void xpath_node_set::_move(xpath_node_set& rhs) PUGIXML_NOEXCEPT { _type = rhs._type; _storage = rhs._storage; @@ -11834,12 +12079,12 @@ namespace pugi if (_begin != &_storage) impl::xml_memory::deallocate(_begin); } - + PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(&_storage), _end(&_storage) { _assign(ns._begin, ns._end, ns._type); } - + PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) { if (this == &ns) return *this; @@ -11849,13 +12094,13 @@ namespace pugi return *this; } -#if __cplusplus >= 201103 - PUGI__FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs): _type(type_unsorted), _begin(&_storage), _end(&_storage) +#ifdef PUGIXML_HAS_MOVE + PUGI__FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT: _type(type_unsorted), _begin(&_storage), _end(&_storage) { _move(rhs); } - PUGI__FN xpath_node_set& xpath_node_set::operator=(xpath_node_set&& rhs) + PUGI__FN xpath_node_set& xpath_node_set::operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT { if (this == &rhs) return *this; @@ -11872,17 +12117,17 @@ namespace pugi { return _type; } - + PUGI__FN size_t xpath_node_set::size() const { return _end - _begin; } - + PUGI__FN bool xpath_node_set::empty() const { return _begin == _end; } - + PUGI__FN const xpath_node& xpath_node_set::operator[](size_t index) const { assert(index < size()); @@ -11893,12 +12138,12 @@ namespace pugi { return _begin; } - + PUGI__FN xpath_node_set::const_iterator xpath_node_set::end() const { return _end; } - + PUGI__FN void xpath_node_set::sort(bool reverse) { _type = impl::xpath_sort(_begin, _end, _type, reverse); @@ -11944,7 +12189,7 @@ namespace pugi return static_cast(this)->name; default: - assert(!"Invalid variable type"); + assert(false && "Invalid variable type"); // unreachable return 0; } } @@ -12049,8 +12294,8 @@ namespace pugi return *this; } -#if __cplusplus >= 201103 - PUGI__FN xpath_variable_set::xpath_variable_set(xpath_variable_set&& rhs) +#ifdef PUGIXML_HAS_MOVE + PUGI__FN xpath_variable_set::xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) { @@ -12059,7 +12304,7 @@ namespace pugi } } - PUGI__FN xpath_variable_set& xpath_variable_set::operator=(xpath_variable_set&& rhs) + PUGI__FN xpath_variable_set& xpath_variable_set::operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT { for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) { @@ -12230,6 +12475,15 @@ namespace pugi _impl = impl.release(); _result.error = 0; } + else + { + #ifdef PUGIXML_NO_EXCEPTIONS + if (qimpl->oom) _result.error = "Out of memory"; + #else + if (qimpl->oom) throw std::bad_alloc(); + throw xpath_exception(_result); + #endif + } } } @@ -12243,14 +12497,16 @@ namespace pugi impl::xpath_query_impl::destroy(static_cast(_impl)); } -#if __cplusplus >= 201103 - PUGI__FN xpath_query::xpath_query(xpath_query&& rhs) +#ifdef PUGIXML_HAS_MOVE + PUGI__FN xpath_query::xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT { _impl = rhs._impl; + _result = rhs._result; rhs._impl = 0; + rhs._result = xpath_parse_result(); } - xpath_query& xpath_query::operator=(xpath_query&& rhs) + PUGI__FN xpath_query& xpath_query::operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT { if (this == &rhs) return *this; @@ -12258,7 +12514,9 @@ namespace pugi impl::xpath_query_impl::destroy(static_cast(_impl)); _impl = rhs._impl; + _result = rhs._result; rhs._impl = 0; + rhs._result = xpath_parse_result(); return *this; } @@ -12274,37 +12532,63 @@ namespace pugi PUGI__FN bool xpath_query::evaluate_boolean(const xpath_node& n) const { if (!_impl) return false; - + impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return false; - #endif - - return static_cast(_impl)->root->eval_boolean(c, sd.stack); + bool r = static_cast(_impl)->root->eval_boolean(c, sd.stack); + + if (sd.oom) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return false; + #else + throw std::bad_alloc(); + #endif + } + + return r; } - + PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const { if (!_impl) return impl::gen_nan(); - + impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return impl::gen_nan(); - #endif + double r = static_cast(_impl)->root->eval_number(c, sd.stack); - return static_cast(_impl)->root->eval_number(c, sd.stack); + if (sd.oom) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return impl::gen_nan(); + #else + throw std::bad_alloc(); + #endif + } + + return r; } #ifndef PUGIXML_NO_STL PUGI__FN string_t xpath_query::evaluate_string(const xpath_node& n) const { + if (!_impl) return string_t(); + + impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; - impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); + impl::xpath_string r = static_cast(_impl)->root->eval_string(c, sd.stack); + + if (sd.oom) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return string_t(); + #else + throw std::bad_alloc(); + #endif + } return string_t(r.c_str(), r.length()); } @@ -12312,12 +12596,22 @@ namespace pugi PUGI__FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const { + impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; - impl::xpath_string r = impl::evaluate_string_impl(static_cast(_impl), n, sd); + impl::xpath_string r = _impl ? static_cast(_impl)->root->eval_string(c, sd.stack) : impl::xpath_string(); + + if (sd.oom) + { + #ifdef PUGIXML_NO_EXCEPTIONS + r = impl::xpath_string(); + #else + throw std::bad_alloc(); + #endif + } size_t full_size = r.length() + 1; - + if (capacity > 0) { size_t size = (full_size < capacity) ? full_size : capacity; @@ -12326,7 +12620,7 @@ namespace pugi memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t)); buffer[size - 1] = 0; } - + return full_size; } @@ -12338,12 +12632,17 @@ namespace pugi impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_node_set(); - #endif - impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_all); + if (sd.oom) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return xpath_node_set(); + #else + throw std::bad_alloc(); + #endif + } + return xpath_node_set(r.begin(), r.end(), r.type()); } @@ -12355,12 +12654,17 @@ namespace pugi impl::xpath_context c(n, 1, 1); impl::xpath_stack_data sd; - #ifdef PUGIXML_NO_EXCEPTIONS - if (setjmp(sd.error_handler)) return xpath_node(); - #endif - impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_first); + if (sd.oom) + { + #ifdef PUGIXML_NO_EXCEPTIONS + return xpath_node(); + #else + throw std::bad_alloc(); + #endif + } + return r.first(); } @@ -12386,7 +12690,7 @@ namespace pugi PUGI__FN xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); - return select_node(q); + return q.evaluate_node(*this); } PUGI__FN xpath_node xml_node::select_node(const xpath_query& query) const @@ -12397,7 +12701,7 @@ namespace pugi PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); - return select_nodes(q); + return q.evaluate_node_set(*this); } PUGI__FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const @@ -12408,7 +12712,7 @@ namespace pugi PUGI__FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const { xpath_query q(query, variables); - return select_single_node(q); + return q.evaluate_node(*this); } PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const @@ -12429,16 +12733,23 @@ namespace pugi # pragma warning(pop) #endif +#if defined(_MSC_VER) && defined(__c2__) +# pragma clang diagnostic pop +#endif + // Undefine all local macros (makes sure we're not leaking macros in header-only mode) #undef PUGI__NO_INLINE #undef PUGI__UNLIKELY #undef PUGI__STATIC_ASSERT #undef PUGI__DMC_VOLATILE +#undef PUGI__UNSIGNED_OVERFLOW #undef PUGI__MSVC_CRT_VERSION +#undef PUGI__SNPRINTF #undef PUGI__NS_BEGIN #undef PUGI__NS_END #undef PUGI__FN #undef PUGI__FN_NO_INLINE +#undef PUGI__GETHEADER_IMPL #undef PUGI__GETPAGE_IMPL #undef PUGI__GETPAGE #undef PUGI__NODETYPE @@ -12460,7 +12771,7 @@ namespace pugi #endif /** - * Copyright (c) 2006-2015 Arseny Kapoulkine + * Copyright (c) 2006-2018 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -12473,7 +12784,7 @@ namespace pugi * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND diff --git a/lib/pugixml/pugixml.h b/lib/pugixml/pugixml.h index cdd24b6d..86403be3 100644 --- a/lib/pugixml/pugixml.h +++ b/lib/pugixml/pugixml.h @@ -1,7 +1,7 @@ /** - * pugixml parser - version 1.6 + * pugixml parser - version 1.9 * -------------------------------------------------------- - * Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) + * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end @@ -13,7 +13,7 @@ #ifndef PUGIXML_VERSION // Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons -# define PUGIXML_VERSION 160 +# define PUGIXML_VERSION 190 #endif // Include user configuration file (this can define various configuration macros) @@ -72,6 +72,44 @@ # endif #endif +// If the platform is known to have move semantics support, compile move ctor/operator implementation +#ifndef PUGIXML_HAS_MOVE +# if __cplusplus >= 201103 +# define PUGIXML_HAS_MOVE +# elif defined(_MSC_VER) && _MSC_VER >= 1600 +# define PUGIXML_HAS_MOVE +# endif +#endif + +// If C++ is 2011 or higher, add 'noexcept' specifiers +#ifndef PUGIXML_NOEXCEPT +# if __cplusplus >= 201103 +# define PUGIXML_NOEXCEPT noexcept +# elif defined(_MSC_VER) && _MSC_VER >= 1900 +# define PUGIXML_NOEXCEPT noexcept +# else +# define PUGIXML_NOEXCEPT +# endif +#endif + +// Some functions can not be noexcept in compact mode +#ifdef PUGIXML_COMPACT +# define PUGIXML_NOEXCEPT_IF_NOT_COMPACT +#else +# define PUGIXML_NOEXCEPT_IF_NOT_COMPACT PUGIXML_NOEXCEPT +#endif + +// If C++ is 2011 or higher, add 'override' qualifiers +#ifndef PUGIXML_OVERRIDE +# if __cplusplus >= 201103 +# define PUGIXML_OVERRIDE override +# elif defined(_MSC_VER) && _MSC_VER >= 1700 +# define PUGIXML_OVERRIDE override +# else +# define PUGIXML_OVERRIDE +# endif +#endif + // Character interface macros #ifdef PUGIXML_WCHAR_MODE # define PUGIXML_TEXT(t) L ## t @@ -133,13 +171,13 @@ namespace pugi // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. const unsigned int parse_eol = 0x0020; - + // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. const unsigned int parse_wconv_attribute = 0x0040; // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. const unsigned int parse_wnorm_attribute = 0x0080; - + // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. const unsigned int parse_declaration = 0x0100; @@ -158,6 +196,11 @@ namespace pugi // is a valid document. This flag is off by default. const unsigned int parse_fragment = 0x1000; + // This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of + // the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments. + // This flag is off by default. + const unsigned int parse_embed_pcdata = 0x2000; + // The default parsing mode. // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. @@ -184,16 +227,16 @@ namespace pugi }; // Formatting flags - + // Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default. const unsigned int format_indent = 0x01; - + // Write encoding-specific BOM to the output stream. This flag is off by default. const unsigned int format_write_bom = 0x02; // Use raw output mode (no indentation and no line breaks are written). This flag is off by default. const unsigned int format_raw = 0x04; - + // Omit default XML declaration even if there is no declaration in the document. This flag is off by default. const unsigned int format_no_declaration = 0x08; @@ -206,6 +249,9 @@ namespace pugi // Write every attribute on a new line with appropriate indentation. This flag is off by default. const unsigned int format_indent_attributes = 0x40; + // Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default. + const unsigned int format_no_empty_element_tags = 0x80; + // The default set of formatting flags. // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none. const unsigned int format_default = format_indent; @@ -225,7 +271,7 @@ namespace pugi class xml_node; class xml_text; - + #ifndef PUGIXML_NO_XPATH class xpath_node; class xpath_node_set; @@ -268,7 +314,7 @@ namespace pugi // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio xml_writer_file(void* file); - virtual void write(const void* data, size_t size); + virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; private: void* file; @@ -283,7 +329,7 @@ namespace pugi xml_writer_stream(std::basic_ostream >& stream); xml_writer_stream(std::basic_ostream >& stream); - virtual void write(const void* data, size_t size); + virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; private: std::basic_ostream >* narrow_stream; @@ -299,13 +345,13 @@ namespace pugi private: xml_attribute_struct* _attr; - + typedef void (*unspecified_bool_type)(xml_attribute***); public: // Default constructor. Constructs an empty attribute. xml_attribute(); - + // Constructs attribute from internal pointer explicit xml_attribute(xml_attribute_struct* attr); @@ -354,6 +400,8 @@ namespace pugi // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set_value(int rhs); bool set_value(unsigned int rhs); + bool set_value(long rhs); + bool set_value(unsigned long rhs); bool set_value(double rhs); bool set_value(float rhs); bool set_value(bool rhs); @@ -367,6 +415,8 @@ namespace pugi xml_attribute& operator=(const char_t* rhs); xml_attribute& operator=(int rhs); xml_attribute& operator=(unsigned int rhs); + xml_attribute& operator=(long rhs); + xml_attribute& operator=(unsigned long rhs); xml_attribute& operator=(double rhs); xml_attribute& operator=(float rhs); xml_attribute& operator=(bool rhs); @@ -417,7 +467,7 @@ namespace pugi // Borland C++ workaround bool operator!() const; - + // Comparison operators (compares wrapped node pointers) bool operator==(const xml_node& r) const; bool operator!=(const xml_node& r) const; @@ -438,7 +488,7 @@ namespace pugi // Get node value, or "" if node is empty or it has no value // Note: For text node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. const char_t* value() const; - + // Get attribute list xml_attribute first_attribute() const; xml_attribute last_attribute() const; @@ -450,7 +500,7 @@ namespace pugi // Get next/previous sibling in the children list of the parent node xml_node next_sibling() const; xml_node previous_sibling() const; - + // Get parent node xml_node parent() const; @@ -478,7 +528,7 @@ namespace pugi // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) bool set_name(const char_t* rhs); bool set_value(const char_t* rhs); - + // Add attribute with specified name. Returns added attribute, or empty attribute on errors. xml_attribute append_attribute(const char_t* name); xml_attribute prepend_attribute(const char_t* name); @@ -532,11 +582,11 @@ namespace pugi template xml_attribute find_attribute(Predicate pred) const { if (!_root) return xml_attribute(); - + for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) if (pred(attrib)) return attrib; - + return xml_attribute(); } @@ -544,11 +594,11 @@ namespace pugi template xml_node find_child(Predicate pred) const { if (!_root) return xml_node(); - + for (xml_node node = first_child(); node; node = node.next_sibling()) if (pred(node)) return node; - + return xml_node(); } @@ -558,7 +608,7 @@ namespace pugi if (!_root) return xml_node(); xml_node cur = first_child(); - + while (cur._root && cur._root != _root) { if (pred(cur)) return cur; @@ -590,7 +640,7 @@ namespace pugi // Recursively traverse subtree with xml_tree_walker bool traverse(xml_tree_walker& walker); - + #ifndef PUGIXML_NO_XPATH // Select single node by evaluating XPath query. Returns first node from the resulting node set. xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const; @@ -601,11 +651,11 @@ namespace pugi xpath_node_set select_nodes(const xpath_query& query) const; // (deprecated: use select_node instead) Select single node by evaluating XPath query. - xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; - xpath_node select_single_node(const xpath_query& query) const; + PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; + PUGIXML_DEPRECATED xpath_node select_single_node(const xpath_query& query) const; #endif - + // Print subtree using a writer object void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; @@ -701,6 +751,8 @@ namespace pugi // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set(int rhs); bool set(unsigned int rhs); + bool set(long rhs); + bool set(unsigned long rhs); bool set(double rhs); bool set(float rhs); bool set(bool rhs); @@ -714,6 +766,8 @@ namespace pugi xml_text& operator=(const char_t* rhs); xml_text& operator=(int rhs); xml_text& operator=(unsigned int rhs); + xml_text& operator=(long rhs); + xml_text& operator=(unsigned long rhs); xml_text& operator=(double rhs); xml_text& operator=(float rhs); xml_text& operator=(bool rhs); @@ -867,11 +921,11 @@ namespace pugi private: int _depth; - + protected: // Get current traversal depth int depth() const; - + public: xml_tree_walker(); virtual ~xml_tree_walker(); @@ -942,13 +996,14 @@ namespace pugi char_t* _buffer; char _memory[192]; - + // Non-copyable semantics xml_document(const xml_document&); - const xml_document& operator=(const xml_document&); + xml_document& operator=(const xml_document&); - void create(); - void destroy(); + void _create(); + void _destroy(); + void _move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; public: // Default constructor, makes empty document @@ -957,6 +1012,12 @@ namespace pugi // Destructor, invalidates all node/attribute handles to this document ~xml_document(); + #ifdef PUGIXML_HAS_MOVE + // Move semantics support + xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; + xml_document& operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; + #endif + // Removes all nodes, leaving the empty document void reset(); @@ -970,7 +1031,7 @@ namespace pugi #endif // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. - xml_parse_result load(const char_t* contents, unsigned int options = parse_default); + PUGIXML_DEPRECATED xml_parse_result load(const char_t* contents, unsigned int options = parse_default); // Load document from zero-terminated string. No encoding conversions are applied. xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); @@ -1051,7 +1112,7 @@ namespace pugi // Non-copyable semantics xpath_variable(const xpath_variable&); xpath_variable& operator=(const xpath_variable&); - + public: // Get variable name const char_t* name() const; @@ -1095,10 +1156,10 @@ namespace pugi xpath_variable_set(const xpath_variable_set& rhs); xpath_variable_set& operator=(const xpath_variable_set& rhs); - #if __cplusplus >= 201103 + #ifdef PUGIXML_HAS_MOVE // Move semantics support - xpath_variable_set(xpath_variable_set&& rhs); - xpath_variable_set& operator=(xpath_variable_set&& rhs); + xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT; + xpath_variable_set& operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT; #endif // Add a new variable or get the existing one, if the types match @@ -1139,29 +1200,29 @@ namespace pugi // Destructor ~xpath_query(); - #if __cplusplus >= 201103 + #ifdef PUGIXML_HAS_MOVE // Move semantics support - xpath_query(xpath_query&& rhs); - xpath_query& operator=(xpath_query&& rhs); + xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT; + xpath_query& operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT; #endif // Get query expression return type xpath_value_type return_type() const; - + // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. bool evaluate_boolean(const xpath_node& n) const; - + // Evaluate expression as double value in the specified context; performs type conversion if necessary. // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. double evaluate_number(const xpath_node& n) const; - + #ifndef PUGIXML_NO_STL // Evaluate expression as string value in the specified context; performs type conversion if necessary. // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. string_t evaluate_string(const xpath_node& n) const; #endif - + // Evaluate expression as string value in the specified context; performs type conversion if necessary. // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. @@ -1188,7 +1249,7 @@ namespace pugi // Borland C++ workaround bool operator!() const; }; - + #ifndef PUGIXML_NO_EXCEPTIONS // XPath exception class class PUGIXML_CLASS xpath_exception: public std::exception @@ -1201,26 +1262,26 @@ namespace pugi explicit xpath_exception(const xpath_parse_result& result); // Get error message - virtual const char* what() const throw(); + virtual const char* what() const throw() PUGIXML_OVERRIDE; // Get parse result const xpath_parse_result& result() const; }; #endif - + // XPath node class (either xml_node or xml_attribute) class PUGIXML_CLASS xpath_node { private: xml_node _node; xml_attribute _attribute; - + typedef void (*unspecified_bool_type)(xpath_node***); public: // Default constructor; constructs empty XPath node xpath_node(); - + // Construct XPath node from XML node/attribute xpath_node(const xml_node& node); xpath_node(const xml_attribute& attribute, const xml_node& parent); @@ -1228,13 +1289,13 @@ namespace pugi // Get node/attribute, if any xml_node node() const; xml_attribute attribute() const; - + // Get parent of contained node/attribute xml_node parent() const; // Safe bool conversion operator operator unspecified_bool_type() const; - + // Borland C++ workaround bool operator!() const; @@ -1260,13 +1321,13 @@ namespace pugi type_sorted, // Sorted by document order (ascending) type_sorted_reverse // Sorted by document order (descending) }; - + // Constant iterator type typedef const xpath_node* const_iterator; // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work typedef const xpath_node* iterator; - + // Default constructor. Constructs empty set. xpath_node_set(); @@ -1275,49 +1336,49 @@ namespace pugi // Destructor ~xpath_node_set(); - + // Copy constructor/assignment operator xpath_node_set(const xpath_node_set& ns); xpath_node_set& operator=(const xpath_node_set& ns); - #if __cplusplus >= 201103 + #ifdef PUGIXML_HAS_MOVE // Move semantics support - xpath_node_set(xpath_node_set&& rhs); - xpath_node_set& operator=(xpath_node_set&& rhs); + xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT; + xpath_node_set& operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT; #endif // Get collection type type_t type() const; - + // Get collection size size_t size() const; // Indexing operator const xpath_node& operator[](size_t index) const; - + // Collection iterators const_iterator begin() const; const_iterator end() const; // Sort the collection in ascending/descending order by document order void sort(bool reverse = false); - + // Get first node in the collection by document order xpath_node first() const; - + // Check if collection is empty bool empty() const; - + private: type_t _type; - + xpath_node _storage; - + xpath_node* _begin; xpath_node* _end; void _assign(const_iterator begin, const_iterator end, type_t type); - void _move(xpath_node_set& rhs); + void _move(xpath_node_set& rhs) PUGIXML_NOEXCEPT; }; #endif @@ -1325,7 +1386,7 @@ namespace pugi // Convert wide string to UTF8 std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const wchar_t* str); std::basic_string, std::allocator > PUGIXML_FUNCTION as_utf8(const std::basic_string, std::allocator >& str); - + // Convert UTF8 to wide string std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const char* str); std::basic_string, std::allocator > PUGIXML_FUNCTION as_wide(const std::basic_string, std::allocator >& str); @@ -1333,13 +1394,13 @@ namespace pugi // Memory allocation function interface; returns pointer to allocated memory or NULL on failure typedef void* (*allocation_function)(size_t size); - + // Memory deallocation function interface typedef void (*deallocation_function)(void* ptr); // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); - + // Get current memory management functions allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); @@ -1375,7 +1436,7 @@ namespace std #endif /** - * Copyright (c) 2006-2015 Arseny Kapoulkine + * Copyright (c) 2006-2018 Arseny Kapoulkine * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -1388,7 +1449,7 @@ namespace std * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND diff --git a/lib/pugixml/readme.txt b/lib/pugixml/readme.txt index faa41d37..5beb08a9 100644 --- a/lib/pugixml/readme.txt +++ b/lib/pugixml/readme.txt @@ -1,6 +1,6 @@ -pugixml 1.6 - an XML processing library +pugixml 1.9 - an XML processing library -Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) +Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) Report bugs and download new versions at http://pugixml.org/ This is the distribution of pugixml, which is a C++ XML processing library, @@ -28,7 +28,7 @@ The distribution contains the following folders: This library is distributed under the MIT License: -Copyright (c) 2006-2015 Arseny Kapoulkine +Copyright (c) 2006-2018 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/lib/serialisation/XmlIO.cc b/lib/serialisation/XmlIO.cc index 8ac7422c..291b8ad1 100644 --- a/lib/serialisation/XmlIO.cc +++ b/lib/serialisation/XmlIO.cc @@ -54,6 +54,11 @@ void XmlWriter::push(const string &s) node_ = node_.append_child(s.c_str()); } +void XmlWriter::pushXmlString(const std::string &s) +{ + +} + void XmlWriter::pop(void) { node_ = node_.parent(); @@ -65,40 +70,47 @@ std::string XmlWriter::XmlString(void) return oss.str(); } -XmlReader::XmlReader(const char *xmlstring,string toplev) : fileName_("") -{ - pugi::xml_parse_result result; - result = doc_.load_string(xmlstring); - if ( !result ) { - cerr << "XML error description (from char *): " << result.description() << "\nXML\n"<< xmlstring << "\n"; - cerr << "XML error offset (from char *) " << result.offset << "\nXML\n"<< xmlstring <<"\n"; - abort(); - } - if ( toplev == std::string("") ) { - node_ = doc_; - } else { - node_ = doc_.child(toplev.c_str()); - } -} - // Reader implementation /////////////////////////////////////////////////////// -XmlReader::XmlReader(const string &fileName,string toplev) : fileName_(fileName) +void XmlReader::initDoc(const std::string &toplev) { - pugi::xml_parse_result result; - result = doc_.load_file(fileName_.c_str()); - if ( !result ) { - cerr << "XML error description: " << result.description() <<" "<< fileName_ <<"\n"; - cerr << "XML error offset : " << result.offset <<" "<< fileName_ <<"\n"; - abort(); - } if ( toplev == std::string("") ) { - node_ = doc_; + node_ = doc_; } else { node_ = doc_.child(toplev.c_str()); } } -bool XmlReader::push(const string &s) +XmlReader::XmlReader(const char *xmlstring, const std::string toplev) +: fileName_("") +{ + auto result = doc_.load_string(xmlstring); + + if ( !result ) { + std::cerr << "XML error description (from char *): " + << result.description() << "\nXML\n"<< xmlstring << "\n"; + std::cerr << "XML error offset (from char *) " + << result.offset << "\nXML\n"<< xmlstring << std::endl; + abort(); + } + initDoc(toplev); +} + +XmlReader::XmlReader(const std::string &fileName, std::string toplev) +: fileName_(fileName) +{ + auto result = doc_.load_file(fileName_.c_str()); + + if ( !result ) { + std::cerr << "XML error description: " + << result.description() <<" "<< fileName_ <<"\n"; + std::cerr << "XML error offset : " + << result.offset <<" "<< fileName_ << std::endl; + abort(); + } + initDoc(toplev); +} + +bool XmlReader::push(const std::string &s) { if (node_.child(s.c_str())) { @@ -129,7 +141,6 @@ bool XmlReader::nextElement(const std::string &s) { return false; } - } template <> diff --git a/lib/serialisation/XmlIO.h b/lib/serialisation/XmlIO.h index e37eb8d9..799c5883 100644 --- a/lib/serialisation/XmlIO.h +++ b/lib/serialisation/XmlIO.h @@ -47,9 +47,10 @@ namespace Grid class XmlWriter: public Writer { public: - XmlWriter(const std::string &fileName,std::string toplev = std::string("grid") ); + XmlWriter(const std::string &fileName, std::string toplev = std::string("grid") ); virtual ~XmlWriter(void); void push(const std::string &s); + void pushXmlString(const std::string &s); void pop(void); template void writeDefault(const std::string &s, const U &x); @@ -65,8 +66,8 @@ namespace Grid class XmlReader: public Reader { public: - XmlReader(const char *xmlstring,std::string toplev = std::string("grid") ); - XmlReader(const std::string &fileName,std::string toplev = std::string("grid") ); + XmlReader(const char *xmlstring, std::string toplev = std::string("grid") ); + XmlReader(const std::string &fileName, std::string toplev = std::string("grid") ); virtual ~XmlReader(void) = default; bool push(const std::string &s); void pop(void); @@ -75,6 +76,8 @@ namespace Grid void readDefault(const std::string &s, U &output); template void readDefault(const std::string &s, std::vector &output); + private: + void initDoc(const std::string &toplev); private: pugi::xml_document doc_; pugi::xml_node node_; From 1569a374a986334775513c4882d406a610855ad8 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 18:32:14 +0100 Subject: [PATCH 033/126] XML interface polish, XML fragments can be pushed into a writer --- lib/parallelIO/IldgIO.h | 19 +++++------ lib/serialisation/XmlIO.cc | 65 ++++++++++++++++++++------------------ lib/serialisation/XmlIO.h | 7 ++-- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index d1a684f3..90c05546 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -248,7 +248,6 @@ class GridLimeReader : public BinaryIO { template void readLimeObject(serialisable_object &object,std::string object_name,std::string record_name) { - std::string xmlstring; // should this be a do while; can we miss a first record?? while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) { @@ -262,7 +261,8 @@ class GridLimeReader : public BinaryIO { limeReaderReadData((void *)&xmlc[0], &nbytes, LimeR); // std::cout << GridLogMessage<< " readLimeObject matches XML " << &xmlc[0] < using namespace Grid; using namespace std; +void Grid::xmlCheckParse(const pugi::xml_parse_result &result, const std::string name) +{ + if (!result) + { + std::cerr << "XML parsing error for " << name << std::endl; + std::cerr << "XML error description: " << result.description() << std::endl; + std::cerr << "XML error offset : " << result.offset << std::endl; + abort(); + } +} + // Writer implementation /////////////////////////////////////////////////////// XmlWriter::XmlWriter(const string &fileName, string toplev) : fileName_(fileName) { @@ -56,7 +67,14 @@ void XmlWriter::push(const string &s) void XmlWriter::pushXmlString(const std::string &s) { + pugi::xml_document doc; + auto result = doc.load_buffer(s.c_str(), s.size()); + xmlCheckParse(result, "fragment\n'" + s +"'"); + for (pugi::xml_node child = doc.first_child(); child; child = child.next_sibling()) + { + node_ = node_.append_copy(child); + } } void XmlWriter::pop(void) @@ -71,8 +89,23 @@ std::string XmlWriter::XmlString(void) } // Reader implementation /////////////////////////////////////////////////////// -void XmlReader::initDoc(const std::string &toplev) +XmlReader::XmlReader(const std::string &s, const bool isBuffer, + std::string toplev) { + pugi::xml_parse_result result; + + if (isBuffer) + { + fileName_ = ""; + result = doc_.load_string(s.c_str()); + xmlCheckParse(result, "string\n'" + s + "'"); + } + else + { + fileName_ = s; + result = doc_.load_file(s.c_str()); + xmlCheckParse(result, "file '" + fileName_ + "'"); + } if ( toplev == std::string("") ) { node_ = doc_; } else { @@ -80,36 +113,6 @@ void XmlReader::initDoc(const std::string &toplev) } } -XmlReader::XmlReader(const char *xmlstring, const std::string toplev) -: fileName_("") -{ - auto result = doc_.load_string(xmlstring); - - if ( !result ) { - std::cerr << "XML error description (from char *): " - << result.description() << "\nXML\n"<< xmlstring << "\n"; - std::cerr << "XML error offset (from char *) " - << result.offset << "\nXML\n"<< xmlstring << std::endl; - abort(); - } - initDoc(toplev); -} - -XmlReader::XmlReader(const std::string &fileName, std::string toplev) -: fileName_(fileName) -{ - auto result = doc_.load_file(fileName_.c_str()); - - if ( !result ) { - std::cerr << "XML error description: " - << result.description() <<" "<< fileName_ <<"\n"; - std::cerr << "XML error offset : " - << result.offset <<" "<< fileName_ << std::endl; - abort(); - } - initDoc(toplev); -} - bool XmlReader::push(const std::string &s) { if (node_.child(s.c_str())) diff --git a/lib/serialisation/XmlIO.h b/lib/serialisation/XmlIO.h index 799c5883..673b2f46 100644 --- a/lib/serialisation/XmlIO.h +++ b/lib/serialisation/XmlIO.h @@ -43,6 +43,7 @@ Author: paboyle namespace Grid { + void xmlCheckParse(const pugi::xml_parse_result &result, const std::string name); class XmlWriter: public Writer { @@ -66,8 +67,8 @@ namespace Grid class XmlReader: public Reader { public: - XmlReader(const char *xmlstring, std::string toplev = std::string("grid") ); - XmlReader(const std::string &fileName, std::string toplev = std::string("grid") ); + XmlReader(const std::string &fileName, const bool isBuffer = false, + std::string toplev = std::string("grid") ); virtual ~XmlReader(void) = default; bool push(const std::string &s); void pop(void); @@ -77,7 +78,7 @@ namespace Grid template void readDefault(const std::string &s, std::vector &output); private: - void initDoc(const std::string &toplev); + void checkParse(const pugi::xml_parse_result &result, const std::string name); private: pugi::xml_document doc_; pugi::xml_node node_; From f117552334824b992a33c7559f9d8868ec3d7860 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 18:38:46 +0100 Subject: [PATCH 034/126] post-merge fix --- lib/serialisation/XmlIO.cc | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/serialisation/XmlIO.cc b/lib/serialisation/XmlIO.cc index f4a5dbdc..bb2b9007 100644 --- a/lib/serialisation/XmlIO.cc +++ b/lib/serialisation/XmlIO.cc @@ -95,22 +95,6 @@ std::string XmlWriter::string(void) return oss.str(); } -XmlReader::XmlReader(const char *xmlstring,std::string toplev) : fileName_("") -{ - pugi::xml_parse_result result; - result = doc_.load_string(xmlstring); - if ( !result ) { - std::cerr << "XML error description (from char *): " << result.description() << "\nXML\n"<< xmlstring << "\n"; - std::cerr << "XML error offset (from char *) " << result.offset << "\nXML\n"<< xmlstring <<"\n"; - abort(); - } - if ( toplev == std::string("") ) { - node_ = doc_; - } else { - node_ = doc_.child(toplev.c_str()); - } -} - // Reader implementation /////////////////////////////////////////////////////// XmlReader::XmlReader(const std::string &s, const bool isBuffer, std::string toplev) From 6b7228b3e649d26e63030fd9458f485804dede3c Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 19:29:53 +0100 Subject: [PATCH 035/126] Hadrons: better metadata for eigenpack --- extras/Hadrons/EigenPack.hpp | 15 +++++++------- extras/Hadrons/Module.hpp | 6 +++--- .../Modules/MSolver/LocalCoherenceLanczos.hpp | 4 ++-- lib/parallelIO/IldgIO.h | 20 +++++++++++-------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index df180e9b..a0bdbf04 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -44,11 +44,9 @@ class EigenPack { public: typedef F Field; - struct PackRecord: Serializable + struct PackRecord { - GRID_SERIALIZABLE_CLASS_MEMBERS(PackRecord, - std::string, operatorPar, - std::string, solverPar); + std::string operatorXml, solverXml; }; struct VecRecord: Serializable { @@ -116,7 +114,7 @@ protected: ScidacReader binReader; binReader.open(filename); - binReader.readScidacFileRecord(evec[0]._grid, record); + binReader.skipPastObjectRecord(SCIDAC_FILE_XML); for(int k = 0; k < size; ++k) { VecRecord vecRecord; @@ -136,10 +134,13 @@ protected: void basicWrite(const std::string filename, std::vector &evec, const unsigned int size) { - ScidacWriter binWriter(evec[0]._grid->IsBoss()); + ScidacWriter binWriter(evec[0]._grid->IsBoss()); + XmlWriter xmlWriter("", ""); + xmlWriter.pushXmlString(record.operatorXml); + xmlWriter.pushXmlString(record.solverXml); + binWriter.writeLimeObject(1, 1, xmlWriter, "parameters", SCIDAC_FILE_XML); binWriter.open(filename); - binWriter.writeScidacFileRecord(evec[0]._grid, record); for(int k = 0; k < size; ++k) { VecRecord vecRecord; diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 08cf49a2..583f1111 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -256,11 +256,11 @@ void Module

::saveParameters(XmlWriter &writer, const std::string name) template std::string Module

::parString(void) const { - std::ostringstream s; + XmlWriter writer("", ""); - s << par(); + write(writer, par_.SerialisableClassName(), par_); - return s.str(); + return writer.string(); } template diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index f4333f80..2b7c1049 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -148,8 +148,8 @@ void TLocalCoherenceLanczos::execute(void) auto &coarsePar = par().coarseParams; auto &epack = envGetDerived(BasePack, CoarsePack, getName()); - epack.record.operatorPar = vm().getModule(par().action)->parString(); - epack.record.solverPar = parString(); + epack.record.operatorXml = vm().getModule(par().action)->parString(); + epack.record.solverXml = parString(); envGetTmp(LCL, solver); LOG(Message) << "Performing fine grid IRL -- Nstop= " << finePar.Nstop << ", Nk= " << finePar.Nk << ", Nm= " diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index 314c5c33..3eb55d7d 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -320,16 +320,11 @@ class GridLimeWriter : public BinaryIO //////////////////////////////////////////// // Write a generic serialisable object //////////////////////////////////////////// - template - void writeLimeObject(int MB,int ME,serialisable_object &object,std::string object_name,std::string record_name) + void writeLimeObject(int MB,int ME,XmlWriter &writer,std::string object_name,std::string record_name) { if ( boss_node ) { - std::string xmlstring; - { - XmlWriter WR("",""); - write(WR,object_name,object); - xmlstring = WR.docString(); - } + std::string xmlstring = writer.docString(); + // std::cout << "WriteLimeObject" << record_name < + void writeLimeObject(int MB,int ME,serialisable_object &object,std::string object_name,std::string record_name) + { + XmlWriter WR("",""); + + write(WR,object_name,object); + writeLimeObject(MB, ME, WR, object_name, record_name); + } //////////////////////////////////////////////////// // Write a generic lattice field and csum // This routine is Collectively called by all nodes From 7c9b0dd84246de48ca5ab4e329d5e9ff516828b1 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 19:32:22 +0100 Subject: [PATCH 036/126] Hadrons: top level name for eigenpack metadata --- extras/Hadrons/EigenPack.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index a0bdbf04..71e0c0f1 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -135,7 +135,7 @@ protected: const unsigned int size) { ScidacWriter binWriter(evec[0]._grid->IsBoss()); - XmlWriter xmlWriter("", ""); + XmlWriter xmlWriter("", "eigenPackPar"); xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); From a16bbecb8a9d53f6ccc55342e8b4db656ddd442b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 19:38:20 +0100 Subject: [PATCH 037/126] Hadrons: more feedback --- extras/Hadrons/EigenPack.hpp | 2 ++ extras/Hadrons/Modules/MSolver/RBPrecCG.hpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 71e0c0f1..a76d02f7 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -119,6 +119,7 @@ protected: { VecRecord vecRecord; + LOG(Message) << "Reading eigenvector " << k << std::endl; binReader.readScidacFieldRecord(evec[k], vecRecord); if (vecRecord.index != k) { @@ -147,6 +148,7 @@ protected: vecRecord.index = k; vecRecord.eval = eval[k]; + LOG(Message) << "Writing eigenvector " << k << std::endl; binWriter.writeScidacFieldRecord(evec[k], vecRecord); } binWriter.close(); diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp index a47bb67e..6e4fbba6 100644 --- a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp @@ -152,6 +152,9 @@ void TRBPrecCG::setup(void) { auto &epack = envGetDerived(EPack, CoarseEPack, par().eigenPack); + LOG(Message) << "using low-mode deflation with coarse eigenpack '" + << par().eigenPack << "' (" + << epack.evecCoarse.size() << " modes)" << std::endl; guesser.reset(new CoarseGuesser(epack.evec, epack.evecCoarse, epack.evalCoarse)); } @@ -159,6 +162,9 @@ void TRBPrecCG::setup(void) { auto &epack = envGet(EPack, par().eigenPack); + LOG(Message) << "using low-mode deflation with eigenpack '" + << par().eigenPack << "' (" + << epack.evec.size() << " modes)" << std::endl; guesser.reset(new FineGuesser(epack.evec, epack.eval)); } } From 17f27b1ebd097159502af0684908e8cd656dd895 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 22:52:11 +0100 Subject: [PATCH 038/126] Hadrons: eigenpack writer fix --- extras/Hadrons/EigenPack.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index a76d02f7..5f403595 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -140,8 +140,8 @@ protected: xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); - binWriter.writeLimeObject(1, 1, xmlWriter, "parameters", SCIDAC_FILE_XML); binWriter.open(filename); + binWriter.writeLimeObject(1, 1, xmlWriter, "parameters", SCIDAC_FILE_XML); for(int k = 0; k < size; ++k) { VecRecord vecRecord; From c8d4d184ee832ecdebe656cd4c17db13509cf455 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 6 Apr 2018 22:53:01 +0100 Subject: [PATCH 039/126] XML push fragment fix --- lib/serialisation/XmlIO.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/serialisation/XmlIO.cc b/lib/serialisation/XmlIO.cc index 050ca6ff..62f2e58c 100644 --- a/lib/serialisation/XmlIO.cc +++ b/lib/serialisation/XmlIO.cc @@ -75,6 +75,7 @@ void XmlWriter::pushXmlString(const std::string &s) { node_ = node_.append_copy(child); } + pop(); } void XmlWriter::pop(void) From 4573b34cac473d0e1b2c72ad6b9145d525366a02 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 13 Apr 2018 18:21:00 +0200 Subject: [PATCH 040/126] Hadrons: scalar SU(N) 2-pt functions with momentum --- .../Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 70 +++++++++++++++---- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index 5227e95a..5ec56714 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -45,6 +45,7 @@ class TwoPointPar: Serializable public: GRID_SERIALIZABLE_CLASS_MEMBERS(TwoPointPar, std::vector, op, + std::vector, mom, std::string, output); }; @@ -52,14 +53,17 @@ template class TTwoPoint: public Module { public: - typedef typename SImpl::Field Field; - typedef typename SImpl::ComplexField ComplexField; + typedef typename SImpl::Field Field; + typedef typename SImpl::ComplexField ComplexField; + typedef std::vector SlicedOp; + class Result: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(Result, std::string, sink, std::string, source, + std::vector, mom, std::vector, data); }; public: @@ -79,6 +83,8 @@ private: template std::vector makeTwoPoint(const std::vector &sink, const std::vector &source); +private: + std::vector> mom_; }; MODULE_REGISTER_NS(TwoPointSU2, TTwoPoint>, MScalarSUN); @@ -115,9 +121,19 @@ std::vector TTwoPoint::getOutput(void) template void TTwoPoint::setup(void) { - const unsigned int nt = env().getDim().back(); - envTmp(std::vector>, "slicedOp", 1, par().op.size(), - std::vector(nt)); + const unsigned int nd = env().getDim().size(); + + mom_.resize(par().mom.size()); + for (unsigned int i = 0; i < mom_.size(); ++i) + { + mom_[i] = strToVec(par().mom[i]); + if (mom_[i].size() != nd - 1) + { + HADRON_ERROR(Size, "momentum number of components different from " + + std::to_string(nd-1)); + } + } + envTmpLat(ComplexField, "ftBuf"); } // execution /////////////////////////////////////////////////////////////////// @@ -130,24 +146,48 @@ void TTwoPoint::execute(void) LOG(Message) << " '" << o << "'" << std::endl; } - const unsigned int nd = env().getDim().size(); - std::vector result; - - envGetTmp(std::vector>, slicedOp); - for (unsigned int i = 0; i < par().op.size(); ++i) + const unsigned int nd = env().getDim().size(); + const unsigned int nt = env().getDim().back(); + const unsigned int nop = par().op.size(); + const unsigned int nmom = mom_.size(); + std::vector dMask(nd, 1); + std::vector result; + std::vector> slicedOp(nop); + FFT fft(env().getGrid()); + + envGetTmp(ComplexField, ftBuf); + dMask[nd - 1] = 0; + for (unsigned int i = 0; i < nop; ++i) { auto &op = envGet(ComplexField, par().op[i]); - sliceSum(op, slicedOp[i], nd - 1); + slicedOp[i].resize(nmom); + LOG(Message) << "Operator '" << par().op[i] << "' FFT" << std::endl; + fft.FFT_dim_mask(ftBuf, op, dMask, FFT::forward); + for (unsigned int m = 0; m < nmom; ++m) + { + auto qt = mom_[m]; + + qt.resize(nd); + slicedOp[i][m].resize(nt); + for (unsigned int t = 0; t < nt; ++t) + { + qt[nd - 1] = t; + peekSite(slicedOp[i][m][t], ftBuf, qt); + } + } } - for (unsigned int i = 0; i < par().op.size(); ++i) - for (unsigned int j = 0; j < par().op.size(); ++j) + LOG(Message) << "Making contractions" << std::endl; + for (unsigned int m = 0; m < nmom; ++m) + for (unsigned int i = 0; i < nop; ++i) + for (unsigned int j = 0; j < nop; ++j) { Result r; r.sink = par().op[i]; r.source = par().op[j]; - r.data = makeTwoPoint(slicedOp[i], slicedOp[j]); + r.mom = mom_[m]; + r.data = makeTwoPoint(slicedOp[i][m], slicedOp[j][m]); result.push_back(r); } saveResult(par().output, "twopt", result); @@ -169,7 +209,7 @@ std::vector TTwoPoint::makeTwoPoint( { for (unsigned int t = 0; t < nt; ++t) { - res[dt] += TensorRemove(trace(sink[(t+dt)%nt]*source[t])); + res[dt] += TensorRemove(trace(sink[(t+dt)%nt]*adj(source[t]))); } res[dt] *= 1./static_cast(nt); } From 4669ecd4bab0ec393f745b7cb179ca850d355449 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 13 Apr 2018 18:21:18 +0200 Subject: [PATCH 041/126] Hadrons: build improvement --- extras/Hadrons/Application.cc | 1 + extras/Hadrons/Application.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/extras/Hadrons/Application.cc b/extras/Hadrons/Application.cc index 8b2aba4a..4c7e71f2 100644 --- a/extras/Hadrons/Application.cc +++ b/extras/Hadrons/Application.cc @@ -28,6 +28,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include +#include using namespace Grid; using namespace QCD; diff --git a/extras/Hadrons/Application.hpp b/extras/Hadrons/Application.hpp index 8cd15433..0254f2fc 100644 --- a/extras/Hadrons/Application.hpp +++ b/extras/Hadrons/Application.hpp @@ -31,7 +31,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include -#include +#include BEGIN_HADRONS_NAMESPACE From 334da7f45262cb119aa9464261d0ecb47a6c5f90 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 13 Apr 2018 18:45:31 +0200 Subject: [PATCH 042/126] Hadrons: can trace which module is throwing an error --- extras/Hadrons/HadronsXmlRun.cc | 12 +++++++++++- extras/Hadrons/VirtualMachine.cc | 13 +++++++++++-- extras/Hadrons/VirtualMachine.hpp | 9 +++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/extras/Hadrons/HadronsXmlRun.cc b/extras/Hadrons/HadronsXmlRun.cc index 4fcfabf2..26e56f7d 100644 --- a/extras/Hadrons/HadronsXmlRun.cc +++ b/extras/Hadrons/HadronsXmlRun.cc @@ -69,7 +69,17 @@ int main(int argc, char *argv[]) } catch (const std::exception& e) { - LOG(Error) << "FATAL ERROR -- Exception " << typeName(&typeid(e)) << std::endl; + auto &vm = VirtualMachine::getInstance(); + int mod = vm.getCurrentModule(); + + LOG(Error) << "FATAL ERROR -- Exception " << typeName(&typeid(e)) + << std::endl; + if (mod >= 0) + { + LOG(Error) << "During execution of module '" + << vm.getModuleName(mod) << "' (address " << mod << ")" + << std::endl; + } LOG(Error) << e.what() << std::endl; LOG(Error) << "Aborting program" << std::endl; Grid_finalize(); diff --git a/extras/Hadrons/VirtualMachine.cc b/extras/Hadrons/VirtualMachine.cc index 2b7f9620..a96df622 100644 --- a/extras/Hadrons/VirtualMachine.cc +++ b/extras/Hadrons/VirtualMachine.cc @@ -250,6 +250,11 @@ std::string VirtualMachine::getModuleNamespace(const std::string name) const return getModuleNamespace(getModuleAddress(name)); } +int VirtualMachine::getCurrentModule(void) const +{ + return currentModule_; +} + bool VirtualMachine::hasModule(const unsigned int address) const { return (address < module_.size()); @@ -468,7 +473,9 @@ void VirtualMachine::memoryProfile(const unsigned int address) << "' (" << address << ")..." << std::endl; try { + currentModule_ = address; m->setup(); + currentModule_ = -1; updateProfile(address); } catch (Exceptions::Definition &) @@ -622,7 +629,7 @@ VirtualMachine::Program VirtualMachine::schedule(const GeneticPar &par) #define SEP "---------------" #define MEM_MSG(size) sizeString(size) -void VirtualMachine::executeProgram(const Program &p) const +void VirtualMachine::executeProgram(const Program &p) { Size memPeak = 0, sizeBefore, sizeAfter; GarbageSchedule freeProg; @@ -650,7 +657,9 @@ void VirtualMachine::executeProgram(const Program &p) const LOG(Message) << SEP << " Measurement step " << i + 1 << "/" << p.size() << " (module '" << module_[p[i]].name << "') " << SEP << std::endl; + currentModule_ = p[i]; (*module_[p[i]].data)(); + currentModule_ = -1; sizeBefore = env().getTotalSize(); // print used memory after execution LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore) @@ -679,7 +688,7 @@ void VirtualMachine::executeProgram(const Program &p) const } } -void VirtualMachine::executeProgram(const std::vector &p) const +void VirtualMachine::executeProgram(const std::vector &p) { Program pAddress; diff --git a/extras/Hadrons/VirtualMachine.hpp b/extras/Hadrons/VirtualMachine.hpp index 68eeb0c0..153f8d70 100644 --- a/extras/Hadrons/VirtualMachine.hpp +++ b/extras/Hadrons/VirtualMachine.hpp @@ -114,6 +114,7 @@ public: std::string getModuleType(const std::string name) const; std::string getModuleNamespace(const unsigned int address) const; std::string getModuleNamespace(const std::string name) const; + int getCurrentModule(void) const; bool hasModule(const unsigned int address) const; bool hasModule(const std::string name) const; // print VM content @@ -133,8 +134,8 @@ public: // genetic scheduler Program schedule(const GeneticPar &par); // general execution - void executeProgram(const Program &p) const; - void executeProgram(const std::vector &p) const; + void executeProgram(const Program &p); + void executeProgram(const std::vector &p); private: // environment shortcut DEFINE_ENV_ALIAS; @@ -154,13 +155,13 @@ private: // module and related maps std::vector module_; std::map moduleAddress_; - std::string currentModule_{""}; + int currentModule_{-1}; // module graph bool graphOutdated_{true}; Graph graph_; // memory profile bool memoryProfileOutdated_{true}; - MemoryProfile profile_; + MemoryProfile profile_; }; /****************************************************************************** From ddcaa6ad299fecc457e0eefb784e75d2d994e3ee Mon Sep 17 00:00:00 2001 From: paboyle Date: Tue, 17 Apr 2018 10:48:33 +0100 Subject: [PATCH 043/126] Master does header on Nersc --- lib/parallelIO/NerscIO.h | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/parallelIO/NerscIO.h b/lib/parallelIO/NerscIO.h index e2c2bc39..0eb52071 100644 --- a/lib/parallelIO/NerscIO.h +++ b/lib/parallelIO/NerscIO.h @@ -237,20 +237,24 @@ namespace Grid { MachineCharacteristics(header); uint64_t offset; - - truncate(file); // Sod it -- always write 3x3 double header.floating_point = std::string("IEEE64BIG"); header.data_type = std::string("4D_SU3_GAUGE_3x3"); GaugeSimpleUnmunger munge; - offset = writeHeader(header,file); + if ( grid->IsBoss() ) { + truncate(file); + offset = writeHeader(header,file); + } + grid->Broadcast(0,(void *)&offset,sizeof(offset)); uint32_t nersc_csum,scidac_csuma,scidac_csumb; BinaryIO::writeLatticeObject(Umu,file,munge,offset,header.floating_point, nersc_csum,scidac_csuma,scidac_csumb); header.checksum = nersc_csum; - writeHeader(header,file); + if ( grid->IsBoss() ) { + writeHeader(header,file); + } std::cout<IsBoss() ) { + truncate(file); + offset = writeHeader(header,file); + } + grid->Broadcast(0,(void *)&offset,sizeof(offset)); + uint32_t nersc_csum,scidac_csuma,scidac_csumb; BinaryIO::writeRNG(serial,parallel,file,offset,nersc_csum,scidac_csuma,scidac_csumb); header.checksum = nersc_csum; - offset = writeHeader(header,file); + if ( grid->IsBoss() ) { + offset = writeHeader(header,file); + } std::cout< Date: Wed, 18 Apr 2018 01:43:29 +0100 Subject: [PATCH 044/126] physical fermion interface, cshift benchmark in SU3. --- benchmarks/Benchmark_su3.cc | 44 ++++++++++++++++++++--- lib/qcd/action/fermion/CayleyFermion5D.cc | 29 +++++++++++++++ lib/qcd/action/fermion/CayleyFermion5D.h | 5 +++ lib/qcd/action/fermion/FermionOperator.h | 13 +++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index 035af2d9..628ad5bd 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -35,7 +35,8 @@ using namespace Grid::QCD; int main (int argc, char ** argv) { Grid_init(&argc,&argv); -#define LMAX (64) +#define LMAX (40) +#define LINC (4) int64_t Nloop=20; @@ -51,7 +52,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -83,7 +84,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -114,7 +115,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -145,7 +146,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -170,5 +171,38 @@ int main (int argc, char ** argv) } + + std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); + int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; + + GridCartesian Grid(latt_size,simd_layout,mpi_layout); + GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(std::vector({45,12,81,9})); + + LatticeColourMatrix z(&Grid); random(pRNG,z); + LatticeColourMatrix x(&Grid); random(pRNG,x); + LatticeColourMatrix y(&Grid); random(pRNG,y); + + for(int mu=0;mu<=4;mu++){ + double start=usecond(); + for(int64_t i=0;i +void CayleyFermion5D::ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d) +{ + int Ls = this->Ls; + FermionField tmp(this->FermionGrid()); + tmp = solution5d; + conformable(solution5d._grid,this->FermionGrid()); + conformable(exported4d._grid,this->GaugeGrid()); + axpby_ssp_pminus(tmp, 0., solution5d, 1., solution5d, 0, 0); + axpby_ssp_pplus (tmp, 1., tmp , 1., solution5d, 0, Ls-1); + ExtractSlice(exported4d, tmp, 0, 0); +} +template +void CayleyFermion5D::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) +{ + int Ls = this->Ls; + FermionField tmp(this->FermionGrid()); + conformable(imported5d._grid,this->FermionGrid()); + conformable(input4d._grid ,this->GaugeGrid()); + tmp = zero; + InsertSlice(input4d, tmp, 0 , 0); + InsertSlice(input4d, tmp, Ls-1, 0); + axpby_ssp_pplus (tmp, 0., tmp, 1., tmp, 0, 0); + axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); + Dminus(tmp,imported5d); +} template void CayleyFermion5D::Dminus(const FermionField &psi, FermionField &chi) { diff --git a/lib/qcd/action/fermion/CayleyFermion5D.h b/lib/qcd/action/fermion/CayleyFermion5D.h index ef75235a..b370b09d 100644 --- a/lib/qcd/action/fermion/CayleyFermion5D.h +++ b/lib/qcd/action/fermion/CayleyFermion5D.h @@ -83,8 +83,13 @@ namespace Grid { virtual void M5D (const FermionField &psi, FermionField &chi); virtual void M5Ddag(const FermionField &psi, FermionField &chi); + /////////////////////////////////////////////////////////////// + // Physical surface field utilities + /////////////////////////////////////////////////////////////// virtual void Dminus(const FermionField &psi, FermionField &chi); virtual void DminusDag(const FermionField &psi, FermionField &chi); + virtual void ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d); + virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d); ///////////////////////////////////////////////////// // Instantiate different versions depending on Impl diff --git a/lib/qcd/action/fermion/FermionOperator.h b/lib/qcd/action/fermion/FermionOperator.h index 1d395d53..5be36f13 100644 --- a/lib/qcd/action/fermion/FermionOperator.h +++ b/lib/qcd/action/fermion/FermionOperator.h @@ -128,6 +128,19 @@ namespace Grid { std::vector mom, unsigned int tmin, unsigned int tmax)=0; + /////////////////////////////////////////////// + // Physical field import/export + /////////////////////////////////////////////// + virtual void Dminus(const FermionField &psi, FermionField &chi) { chi=psi; } + virtual void DminusDag(const FermionField &psi, FermionField &chi) { chi=psi; } + virtual void ImportPhysicalFermionSource(const FermionField &input,FermionField &imported) + { + imported = input; + }; + virtual void ExportPhysicalFermionSolution(const FermionField &solution,FermionField &exported) + { + exported=solution; + }; }; } From 870b1a85aebc8bf545a162053fb04823fd937fa2 Mon Sep 17 00:00:00 2001 From: paboyle Date: Wed, 18 Apr 2018 14:17:49 +0100 Subject: [PATCH 045/126] Think I have the physical prop interface to CF and PF overlap right, but need a strong check/regression. Only support Hw overlap, not Ht for now. Ht needs a new Dminus implemented. --- .../fermion/ContinuedFractionFermion5D.cc | 21 +++++++++++++++++++ .../fermion/ContinuedFractionFermion5D.h | 8 +++++++ .../fermion/PartialFractionFermion5D.cc | 21 +++++++++++++++++++ .../action/fermion/PartialFractionFermion5D.h | 6 ++++++ 4 files changed, 56 insertions(+) diff --git a/lib/qcd/action/fermion/ContinuedFractionFermion5D.cc b/lib/qcd/action/fermion/ContinuedFractionFermion5D.cc index 5d39ef9b..f6857115 100644 --- a/lib/qcd/action/fermion/ContinuedFractionFermion5D.cc +++ b/lib/qcd/action/fermion/ContinuedFractionFermion5D.cc @@ -295,6 +295,27 @@ namespace Grid { assert((Ls&0x1)==1); // Odd Ls required } + template + void ContinuedFractionFermion5D::ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d) + { + int Ls = this->Ls; + conformable(solution5d._grid,this->FermionGrid()); + conformable(exported4d._grid,this->GaugeGrid()); + ExtractSlice(exported4d, solution5d, Ls-1, Ls-1); + } + template + void ContinuedFractionFermion5D::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) + { + int Ls = this->Ls; + conformable(imported5d._grid,this->FermionGrid()); + conformable(input4d._grid ,this->GaugeGrid()); + FermionField tmp(this->FermionGrid()); + tmp=zero; + InsertSlice(input4d, tmp, Ls-1, Ls-1); + tmp=Gamma(Gamma::Algebra::Gamma5)*tmp; + this->Dminus(tmp,imported5d); + } + FermOpTemplateInstantiate(ContinuedFractionFermion5D); } diff --git a/lib/qcd/action/fermion/ContinuedFractionFermion5D.h b/lib/qcd/action/fermion/ContinuedFractionFermion5D.h index e1e50aa5..b551fc28 100644 --- a/lib/qcd/action/fermion/ContinuedFractionFermion5D.h +++ b/lib/qcd/action/fermion/ContinuedFractionFermion5D.h @@ -65,6 +65,14 @@ namespace Grid { // Efficient support for multigrid coarsening virtual void Mdir (const FermionField &in, FermionField &out,int dir,int disp); + /////////////////////////////////////////////////////////////// + // Physical surface field utilities + /////////////////////////////////////////////////////////////// + // virtual void Dminus(const FermionField &psi, FermionField &chi); // Inherit trivial case + // virtual void DminusDag(const FermionField &psi, FermionField &chi); // Inherit trivial case + virtual void ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d); + virtual void ImportPhysicalFermionSource (const FermionField &input4d,FermionField &imported5d); + // Constructors ContinuedFractionFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, diff --git a/lib/qcd/action/fermion/PartialFractionFermion5D.cc b/lib/qcd/action/fermion/PartialFractionFermion5D.cc index 3a78e043..11840027 100644 --- a/lib/qcd/action/fermion/PartialFractionFermion5D.cc +++ b/lib/qcd/action/fermion/PartialFractionFermion5D.cc @@ -396,6 +396,27 @@ namespace Grid { amax=zolo_hi; } + template + void PartialFractionFermion5D::ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d) + { + int Ls = this->Ls; + conformable(solution5d._grid,this->FermionGrid()); + conformable(exported4d._grid,this->GaugeGrid()); + ExtractSlice(exported4d, solution5d, Ls-1, Ls-1); + } + template + void PartialFractionFermion5D::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) + { + int Ls = this->Ls; + conformable(imported5d._grid,this->FermionGrid()); + conformable(input4d._grid ,this->GaugeGrid()); + FermionField tmp(this->FermionGrid()); + tmp=zero; + InsertSlice(input4d, tmp, Ls-1, Ls-1); + tmp=Gamma(Gamma::Algebra::Gamma5)*tmp; + this->Dminus(tmp,imported5d); + } + // Constructors template PartialFractionFermion5D::PartialFractionFermion5D(GaugeField &_Umu, diff --git a/lib/qcd/action/fermion/PartialFractionFermion5D.h b/lib/qcd/action/fermion/PartialFractionFermion5D.h index 0ec72de4..91f1bd3c 100644 --- a/lib/qcd/action/fermion/PartialFractionFermion5D.h +++ b/lib/qcd/action/fermion/PartialFractionFermion5D.h @@ -70,6 +70,12 @@ namespace Grid { // Efficient support for multigrid coarsening virtual void Mdir (const FermionField &in, FermionField &out,int dir,int disp); + /////////////////////////////////////////////////////////////// + // Physical surface field utilities + /////////////////////////////////////////////////////////////// + virtual void ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d); + virtual void ImportPhysicalFermionSource (const FermionField &input4d,FermionField &imported5d); + // Constructors PartialFractionFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, From c11a3ca0a74096ad2eea03487105fbc7924b625a Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 20 Apr 2018 17:13:04 +0100 Subject: [PATCH 046/126] vectorise/unvectorise in reverse order --- lib/lattice/Lattice_transfer.h | 93 ++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/lib/lattice/Lattice_transfer.h b/lib/lattice/Lattice_transfer.h index 44f0337d..f988f310 100644 --- a/lib/lattice/Lattice_transfer.h +++ b/lib/lattice/Lattice_transfer.h @@ -599,6 +599,51 @@ unvectorizeToLexOrdArray(std::vector &out, const Lattice &in) extract1(in_vobj, out_ptrs, 0); } } + +template +typename std::enable_if::value && !isSIMDvectorized::value, void>::type +unvectorizeToRevLexOrdArray(std::vector &out, const Lattice &in) +{ + + typedef typename vobj::vector_type vtype; + + GridBase* in_grid = in._grid; + out.resize(in_grid->lSites()); + + int ndim = in_grid->Nd(); + int in_nsimd = vtype::Nsimd(); + + std::vector > in_icoor(in_nsimd); + + for(int lane=0; lane < in_nsimd; lane++){ + in_icoor[lane].resize(ndim); + in_grid->iCoorFromIindex(in_icoor[lane], lane); + } + + parallel_for(int in_oidx = 0; in_oidx < in_grid->oSites(); in_oidx++){ //loop over outer index + //Assemble vector of pointers to output elements + std::vector out_ptrs(in_nsimd); + + std::vector in_ocoor(ndim); + in_grid->oCoorFromOindex(in_ocoor, in_oidx); + + std::vector lcoor(in_grid->Nd()); + + for(int lane=0; lane < in_nsimd; lane++){ + for(int mu=0;mu_rdimensions[mu]*in_icoor[lane][mu]; + + int lex; + Lexicographic::IndexFromCoorReversed(lcoor, lex, in_grid->_ldimensions); + out_ptrs[lane] = &out[lex]; + } + + //Unpack into those ptrs + const vobj & in_vobj = in._odata[in_oidx]; + extract1(in_vobj, out_ptrs, 0); + } +} + //Copy SIMD-vectorized lattice to array of scalar objects in lexicographic order template typename std::enable_if::value @@ -648,6 +693,54 @@ vectorizeFromLexOrdArray( std::vector &in, Lattice &out) } } +template +typename std::enable_if::value + && !isSIMDvectorized::value, void>::type +vectorizeFromRevLexOrdArray( std::vector &in, Lattice &out) +{ + + typedef typename vobj::vector_type vtype; + + GridBase* grid = out._grid; + assert(in.size()==grid->lSites()); + + int ndim = grid->Nd(); + int nsimd = vtype::Nsimd(); + + std::vector > icoor(nsimd); + + for(int lane=0; lane < nsimd; lane++){ + icoor[lane].resize(ndim); + grid->iCoorFromIindex(icoor[lane],lane); + } + + parallel_for(uint64_t oidx = 0; oidx < grid->oSites(); oidx++){ //loop over outer index + //Assemble vector of pointers to output elements + std::vector ptrs(nsimd); + + std::vector ocoor(ndim); + grid->oCoorFromOindex(ocoor, oidx); + + std::vector lcoor(grid->Nd()); + + for(int lane=0; lane < nsimd; lane++){ + + for(int mu=0;mu_rdimensions[mu]*icoor[lane][mu]; + } + + int lex; + Lexicographic::IndexFromCoorReversed(lcoor, lex, grid->_ldimensions); + ptrs[lane] = &in[lex]; + } + + //pack from those ptrs + vobj vecobj; + merge1(vecobj, ptrs, 0); + out._odata[oidx] = vecobj; + } +} + //Convert a Lattice from one precision to another template void precisionChange(Lattice &out, const Lattice &in){ From 94edf9cf8be8eb2fe8990db39c3c07c4a38bd71b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 20 Apr 2018 17:13:21 +0100 Subject: [PATCH 047/126] HDF5: direct access to group for custom operations --- lib/serialisation/Hdf5IO.cc | 10 ++++++++++ lib/serialisation/Hdf5IO.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/lib/serialisation/Hdf5IO.cc b/lib/serialisation/Hdf5IO.cc index 1fb7be0c..b915a988 100644 --- a/lib/serialisation/Hdf5IO.cc +++ b/lib/serialisation/Hdf5IO.cc @@ -55,6 +55,11 @@ void Hdf5Writer::writeDefault(const std::string &s, const char *x) writeDefault(s, sx); } +Group & Hdf5Writer::getGroup(void) +{ + return group_; +} + // Reader implementation /////////////////////////////////////////////////////// Hdf5Reader::Hdf5Reader(const std::string &fileName) : fileName_(fileName) @@ -103,3 +108,8 @@ void Hdf5Reader::readDefault(const std::string &s, std::string &x) x.resize(strType.getSize()); attribute.read(strType, &(x[0])); } + +Group & Hdf5Reader::getGroup(void) +{ + return group_; +} diff --git a/lib/serialisation/Hdf5IO.h b/lib/serialisation/Hdf5IO.h index 12625ab8..1ae2791e 100644 --- a/lib/serialisation/Hdf5IO.h +++ b/lib/serialisation/Hdf5IO.h @@ -38,6 +38,7 @@ namespace Grid template typename std::enable_if>::is_number, void>::type writeDefault(const std::string &s, const std::vector &x); + H5NS::Group & getGroup(void); private: template void writeSingleAttribute(const U &x, const std::string &name, @@ -65,6 +66,7 @@ namespace Grid template typename std::enable_if>::is_number, void>::type readDefault(const std::string &s, std::vector &x); + H5NS::Group & getGroup(void); private: template void readSingleAttribute(U &x, const std::string &name, From 141da3ae71b255d0c175016a2e2dc03ee241487a Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 20 Apr 2018 17:13:34 +0100 Subject: [PATCH 048/126] function to get tensor dimensions --- lib/serialisation/VectorUtils.h | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/serialisation/VectorUtils.h b/lib/serialisation/VectorUtils.h index f5c76b84..53088998 100644 --- a/lib/serialisation/VectorUtils.h +++ b/lib/serialisation/VectorUtils.h @@ -30,6 +30,48 @@ namespace Grid { typedef typename std::vector::type>> type; }; + template + void tensorDim(std::vector &dim, const T &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + } + + template + void tensorDim(std::vector &dim, const iScalar &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + tensorDim(dim, t._internal, false); + } + + template + void tensorDim(std::vector &dim, const iVector &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + dim.push_back(N); + tensorDim(dim, t._internal[0], false); + } + + template + void tensorDim(std::vector &dim, const iMatrix &t, const bool wipe = true) + { + if (wipe) + { + dim.clear(); + } + dim.push_back(N); + dim.push_back(N); + tensorDim(dim, t._internal[0][0], false); + } + template typename TensorToVec::type tensorToVec(const T &t) { From b0b5b34bfff8d3ac85825e56b5af130420c28e6f Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 12:48:00 +0100 Subject: [PATCH 049/126] Hadrons: custom abort with module trace --- extras/Hadrons/Exceptions.cc | 24 ++++++++++++++++++++++++ extras/Hadrons/Exceptions.hpp | 4 ++++ extras/Hadrons/HadronsXmlRun.cc | 17 +---------------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/extras/Hadrons/Exceptions.cc b/extras/Hadrons/Exceptions.cc index eedc03b1..e87181b2 100644 --- a/extras/Hadrons/Exceptions.cc +++ b/extras/Hadrons/Exceptions.cc @@ -27,6 +27,8 @@ See the full license in the file "LICENSE" in the top level distribution directo /* END LEGAL */ #include +#include +#include #ifndef ERR_SUFF #define ERR_SUFF " (" + loc + ")" @@ -47,6 +49,7 @@ CONST_EXC(Definition, Logic("definition error: " + msg, loc)) CONST_EXC(Implementation, Logic("implementation error: " + msg, loc)) CONST_EXC(Range, Logic("range error: " + msg, loc)) CONST_EXC(Size, Logic("size error: " + msg, loc)) + // runtime errors CONST_EXC(Runtime, runtime_error(msg + ERR_SUFF)) CONST_EXC(Argument, Runtime("argument error: " + msg, loc)) @@ -55,3 +58,24 @@ CONST_EXC(Memory, Runtime("memory error: " + msg, loc)) CONST_EXC(Parsing, Runtime("parsing error: " + msg, loc)) CONST_EXC(Program, Runtime("program error: " + msg, loc)) CONST_EXC(System, Runtime("system error: " + msg, loc)) + +// abort functions +void Grid::Hadrons::Exceptions::abort(const std::exception& e) +{ + auto &vm = VirtualMachine::getInstance(); + int mod = vm.getCurrentModule(); + + LOG(Error) << "FATAL ERROR -- Exception " << typeName(&typeid(e)) + << std::endl; + if (mod >= 0) + { + LOG(Error) << "During execution of module '" + << vm.getModuleName(mod) << "' (address " << mod << ")" + << std::endl; + } + LOG(Error) << e.what() << std::endl; + LOG(Error) << "Aborting program" << std::endl; + Grid_finalize(); + + exit(EXIT_FAILURE); +} diff --git a/extras/Hadrons/Exceptions.hpp b/extras/Hadrons/Exceptions.hpp index ce11618a..adf2340f 100644 --- a/extras/Hadrons/Exceptions.hpp +++ b/extras/Hadrons/Exceptions.hpp @@ -56,6 +56,7 @@ namespace Exceptions DECL_EXC(Implementation, Logic); DECL_EXC(Range, Logic); DECL_EXC(Size, Logic); + // runtime errors DECL_EXC(Runtime, std::runtime_error); DECL_EXC(Argument, Runtime); @@ -64,6 +65,9 @@ namespace Exceptions DECL_EXC(Parsing, Runtime); DECL_EXC(Program, Runtime); DECL_EXC(System, Runtime); + + // abort functions + void abort(const std::exception& e); } END_HADRONS_NAMESPACE diff --git a/extras/Hadrons/HadronsXmlRun.cc b/extras/Hadrons/HadronsXmlRun.cc index 26e56f7d..6b613bb4 100644 --- a/extras/Hadrons/HadronsXmlRun.cc +++ b/extras/Hadrons/HadronsXmlRun.cc @@ -69,22 +69,7 @@ int main(int argc, char *argv[]) } catch (const std::exception& e) { - auto &vm = VirtualMachine::getInstance(); - int mod = vm.getCurrentModule(); - - LOG(Error) << "FATAL ERROR -- Exception " << typeName(&typeid(e)) - << std::endl; - if (mod >= 0) - { - LOG(Error) << "During execution of module '" - << vm.getModuleName(mod) << "' (address " << mod << ")" - << std::endl; - } - LOG(Error) << e.what() << std::endl; - LOG(Error) << "Aborting program" << std::endl; - Grid_finalize(); - - return EXIT_FAILURE; + Exceptions::abort(e); } // epilogue From c6125b01ceb6957d751fa01abc67ba6a4a1e6651 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 12:48:17 +0100 Subject: [PATCH 050/126] Hadrons: Error and Warning channels always on --- extras/Hadrons/Global.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/Hadrons/Global.cc b/extras/Hadrons/Global.cc index 0164a1ab..32060460 100644 --- a/extras/Hadrons/Global.cc +++ b/extras/Hadrons/Global.cc @@ -57,8 +57,8 @@ void Hadrons::initLogger(void) GridLogIterative.setChanWidth(cw); GridLogDebug.setChanWidth(cw); GridLogIRL.setChanWidth(cw); - HadronsLogError.Active(GridLogError.isActive()); - HadronsLogWarning.Active(GridLogWarning.isActive()); + HadronsLogError.Active(true); + HadronsLogWarning.Active(true); HadronsLogMessage.Active(GridLogMessage.isActive()); HadronsLogIterative.Active(GridLogIterative.isActive()); HadronsLogDebug.Active(GridLogDebug.isActive()); From 169f405c9cf562de935245e8fc9a5e9a161aba6d Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 12:48:34 +0100 Subject: [PATCH 051/126] Hadrons: tests repaired --- tests/hadrons/Test_QED.cc | 1 + tests/hadrons/Test_hadrons.hpp | 1 + tests/hadrons/Test_hadrons_2AS_spectrum.cc | 169 --------------------- tests/hadrons/Test_hadrons_meson_3pt.cc | 1 + tests/hadrons/Test_hadrons_quark.cc | 1 - tests/hadrons/Test_hadrons_spectrum.cc | 1 + tests/hadrons/Test_hadrons_wilsonFund.cc | 1 + 7 files changed, 5 insertions(+), 170 deletions(-) delete mode 100644 tests/hadrons/Test_hadrons_2AS_spectrum.cc diff --git a/tests/hadrons/Test_QED.cc b/tests/hadrons/Test_QED.cc index 3377bf3c..922d67c3 100644 --- a/tests/hadrons/Test_QED.cc +++ b/tests/hadrons/Test_QED.cc @@ -27,6 +27,7 @@ *******************************************************************************/ #include +#include using namespace Grid; using namespace Hadrons; diff --git a/tests/hadrons/Test_hadrons.hpp b/tests/hadrons/Test_hadrons.hpp index 67124d6c..fc061459 100644 --- a/tests/hadrons/Test_hadrons.hpp +++ b/tests/hadrons/Test_hadrons.hpp @@ -26,6 +26,7 @@ *******************************************************************************/ #include +#include using namespace Grid; using namespace Hadrons; diff --git a/tests/hadrons/Test_hadrons_2AS_spectrum.cc b/tests/hadrons/Test_hadrons_2AS_spectrum.cc deleted file mode 100644 index b3906730..00000000 --- a/tests/hadrons/Test_hadrons_2AS_spectrum.cc +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - Grid physics library, www.github.com/paboyle/Grid - - Source file: tests/hadrons/Test_hadrons_spectrum.cc - - Copyright (C) 2015 - - Author: Antonin Portelli - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - See the full license in the file "LICENSE" in the top level distribution - directory. - *******************************************************************************/ - -#include - -using namespace Grid; -using namespace Hadrons; - - - BEGIN_HADRONS_NAMESPACE - BEGIN_MODULE_NAMESPACE(MFermion) - MODULE_REGISTER_NS(GaugeProp2AS, TGaugeProp, MFermion); - END_MODULE_NAMESPACE - BEGIN_MODULE_NAMESPACE(MSource) - MODULE_REGISTER_NS(Point2AS, TPoint, MSource); - END_MODULE_NAMESPACE - BEGIN_MODULE_NAMESPACE(MContraction) - MODULE_REGISTER_NS(Meson2AS, ARG(TMeson), MContraction); -// MODULE_REGISTER_NS(BaryonMultirep, ARG(TBaryon), MContraction); - END_MODULE_NAMESPACE - BEGIN_MODULE_NAMESPACE(MSink) - MODULE_REGISTER_NS(ScalarPoint2AS, TPoint, MSink); - END_MODULE_NAMESPACE - BEGIN_MODULE_NAMESPACE(MSolver) - MODULE_REGISTER_NS(RBPrecCG2AS, TRBPrecCG, MSolver); - END_MODULE_NAMESPACE - BEGIN_MODULE_NAMESPACE(MAction) - MODULE_REGISTER_NS(WilsonClover2AS, TWilsonClover, MAction); - END_MODULE_NAMESPACE - END_HADRONS_NAMESPACE - - -int main(int argc, char *argv[]) -{ - // initialization ////////////////////////////////////////////////////////// - Grid_init(&argc, &argv); - HadronsLogError.Active(GridLogError.isActive()); - HadronsLogWarning.Active(GridLogWarning.isActive()); - HadronsLogMessage.Active(GridLogMessage.isActive()); - HadronsLogIterative.Active(GridLogIterative.isActive()); - HadronsLogDebug.Active(GridLogDebug.isActive()); - LOG(Message) << "Grid initialized" << std::endl; - // run setup /////////////////////////////////////////////////////////////// - Application application; - std::vector flavour = {"l", "s"}; - std::vector mass = {-0.01, -0.04}; - double csw = 1.0; - // global parameters - Application::GlobalPar globalPar; - globalPar.trajCounter.start = 1500; - globalPar.trajCounter.end = 1520; - globalPar.trajCounter.step = 20; - globalPar.seed = "1 2 3 4"; - application.setPar(globalPar); - // gauge field - application.createModule("gauge"); - MSource::Point2AS::Par ptPar; - ptPar.position = "0 0 0 0"; - application.createModule("pt", ptPar); - // sink - MSink::ScalarPoint2AS::Par sinkPar; - sinkPar.mom = "0 0 0"; - application.createModule("sink", sinkPar); - - // set fermion boundary conditions to be periodic space, antiperiodic time. - std::string boundary = "1 1 1 -1"; - - for (unsigned int i = 0; i < flavour.size(); ++i) - { - // actions - MAction::WilsonClover2AS::Par actionPar; - actionPar.gauge = "gauge"; - actionPar.mass = mass[i]; - actionPar.csw_r = csw; - actionPar.csw_t = csw; - actionPar.clover_anisotropy.isAnisotropic= false; - actionPar.clover_anisotropy.t_direction = Nd-1 ; - actionPar.clover_anisotropy.xi_0 = 1.0 ; - actionPar.clover_anisotropy.nu = 1.0 ; - actionPar.boundary = boundary; - application.createModule("WilsonClover2AS_" + flavour[i], actionPar); - - // solvers - MSolver::RBPrecCG2AS::Par solverPar; - solverPar.action = "WilsonClover2AS_" + flavour[i]; - solverPar.residual = 1.0e-8; - solverPar.maxIteration = 10000; - application.createModule("CG_" + flavour[i], - solverPar); - - // propagators - MFermion::GaugeProp2AS::Par quarkPar; - quarkPar.solver = "CG_" + flavour[i]; - quarkPar.source = "pt"; - application.createModule("Qpt_" + flavour[i], quarkPar); - quarkPar.source = "z2"; - application.createModule("QZ2_" + flavour[i], quarkPar); - } - for (unsigned int i = 0; i < flavour.size(); ++i) - for (unsigned int j = i; j < flavour.size(); ++j) - { - MContraction::Meson2AS::Par mesPar; - - mesPar.output = "mesons2AS/pt_" + flavour[i] + flavour[j]; - mesPar.q1 = "Qpt_" + flavour[i]; - mesPar.q2 = "Qpt_" + flavour[j]; - mesPar.gammas = "all"; - mesPar.sink = "sink"; - application.createModule("meson_pt_" - + flavour[i] + flavour[j], - mesPar); - - // mesPar.output = "mesons2AS/Z2_" + flavour[i] + flavour[j]; - // mesPar.q1 = "QZ2_" + flavour[i]; - // mesPar.q2 = "QZ2_" + flavour[j]; - // mesPar.gammas = "all"; - // mesPar.sink = "sink"; - // application.createModule("meson_Z2_" - // + flavour[i] + flavour[j], - // mesPar); - } - for (unsigned int i = 0; i < flavour.size(); ++i) - for (unsigned int j = i; j < flavour.size(); ++j) - for (unsigned int k = j; k < flavour.size(); ++k) - { - MContraction::Baryon::Par barPar; - - barPar.output = "baryons/pt_" + flavour[i] + flavour[j] + flavour[k]; - barPar.q1 = "Qpt_" + flavour[i]; - barPar.q2 = "Qpt_" + flavour[j]; - barPar.q3 = "Qpt_" + flavour[k]; - application.createModule( - "baryon_pt_" + flavour[i] + flavour[j] + flavour[k], barPar); - } - - // execution - application.saveParameterFile("spectrum.xml"); - application.run(); - - // epilogue - LOG(Message) << "Grid is finalizing now" << std::endl; - Grid_finalize(); - - return EXIT_SUCCESS; -} diff --git a/tests/hadrons/Test_hadrons_meson_3pt.cc b/tests/hadrons/Test_hadrons_meson_3pt.cc index b12ef472..243ffebb 100644 --- a/tests/hadrons/Test_hadrons_meson_3pt.cc +++ b/tests/hadrons/Test_hadrons_meson_3pt.cc @@ -26,6 +26,7 @@ *******************************************************************************/ #include +#include using namespace Grid; using namespace Hadrons; diff --git a/tests/hadrons/Test_hadrons_quark.cc b/tests/hadrons/Test_hadrons_quark.cc index cf3d2590..64cbfd30 100644 --- a/tests/hadrons/Test_hadrons_quark.cc +++ b/tests/hadrons/Test_hadrons_quark.cc @@ -26,7 +26,6 @@ *******************************************************************************/ #include "Test_hadrons.hpp" -#include using namespace Grid; using namespace QCD; diff --git a/tests/hadrons/Test_hadrons_spectrum.cc b/tests/hadrons/Test_hadrons_spectrum.cc index 682dcc9b..f41bd5b4 100644 --- a/tests/hadrons/Test_hadrons_spectrum.cc +++ b/tests/hadrons/Test_hadrons_spectrum.cc @@ -26,6 +26,7 @@ *******************************************************************************/ #include +#include using namespace Grid; using namespace Hadrons; diff --git a/tests/hadrons/Test_hadrons_wilsonFund.cc b/tests/hadrons/Test_hadrons_wilsonFund.cc index 36e751b6..bad0f2d3 100644 --- a/tests/hadrons/Test_hadrons_wilsonFund.cc +++ b/tests/hadrons/Test_hadrons_wilsonFund.cc @@ -26,6 +26,7 @@ *******************************************************************************/ #include +#include using namespace Grid; using namespace Hadrons; From 853a5528dc36a1c4d4050a817810c74ce4391d63 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 17:35:01 +0100 Subject: [PATCH 052/126] Hadrons: template modules compilation optimisation --- extras/Hadrons/Application.hpp | 2 +- extras/Hadrons/Module.hpp | 37 ++++++------------- extras/Hadrons/Modules.hpp | 30 --------------- extras/Hadrons/Modules/MAction/DWF.cc | 8 ++++ extras/Hadrons/Modules/MAction/DWF.hpp | 3 +- extras/Hadrons/Modules/MAction/Wilson.cc | 8 ++++ extras/Hadrons/Modules/MAction/Wilson.hpp | 2 +- .../Hadrons/Modules/MAction/WilsonClover.cc | 8 ++++ .../Hadrons/Modules/MAction/WilsonClover.hpp | 2 +- extras/Hadrons/Modules/MAction/ZMobiusDWF.cc | 8 ++++ extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp | 2 +- extras/Hadrons/Modules/MContraction/Baryon.cc | 8 ++++ .../Hadrons/Modules/MContraction/Baryon.hpp | 2 +- .../Hadrons/Modules/MContraction/DiscLoop.cc | 8 ++++ .../Hadrons/Modules/MContraction/DiscLoop.hpp | 2 +- .../Hadrons/Modules/MContraction/Gamma3pt.cc | 8 ++++ .../Hadrons/Modules/MContraction/Gamma3pt.hpp | 2 +- extras/Hadrons/Modules/MContraction/Meson.cc | 8 ++++ extras/Hadrons/Modules/MContraction/Meson.hpp | 2 +- .../Modules/MContraction/WardIdentity.cc | 8 ++++ .../Modules/MContraction/WardIdentity.hpp | 2 +- .../Modules/MContraction/WeakHamiltonian.hpp | 2 +- extras/Hadrons/Modules/MFermion/GaugeProp.cc | 8 ++++ extras/Hadrons/Modules/MFermion/GaugeProp.hpp | 2 +- extras/Hadrons/Modules/MGauge/FundtoHirep.hpp | 6 +-- extras/Hadrons/Modules/MGauge/Random.hpp | 2 +- extras/Hadrons/Modules/MGauge/StochEm.hpp | 2 +- extras/Hadrons/Modules/MGauge/Unit.hpp | 2 +- extras/Hadrons/Modules/MIO/LoadBinary.cc | 13 +++++++ extras/Hadrons/Modules/MIO/LoadBinary.hpp | 12 +++--- .../Modules/MIO/LoadCoarseEigenPack.cc | 8 ++++ .../Modules/MIO/LoadCoarseEigenPack.hpp | 3 +- extras/Hadrons/Modules/MIO/LoadEigenPack.cc | 8 ++++ extras/Hadrons/Modules/MIO/LoadEigenPack.hpp | 2 +- extras/Hadrons/Modules/MIO/LoadNersc.hpp | 2 +- extras/Hadrons/Modules/MLoop/NoiseLoop.cc | 8 ++++ extras/Hadrons/Modules/MLoop/NoiseLoop.hpp | 2 +- .../Hadrons/Modules/MScalar/ChargedProp.hpp | 2 +- extras/Hadrons/Modules/MScalar/FreeProp.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/Div.cc | 12 ++++++ extras/Hadrons/Modules/MScalarSUN/Div.hpp | 10 ++--- extras/Hadrons/Modules/MScalarSUN/EMT.cc | 12 ++++++ extras/Hadrons/Modules/MScalarSUN/EMT.hpp | 10 ++--- .../Hadrons/Modules/MScalarSUN/ShiftProbe.cc | 12 ++++++ .../Hadrons/Modules/MScalarSUN/ShiftProbe.hpp | 10 ++--- .../Hadrons/Modules/MScalarSUN/TrKinetic.cc | 12 ++++++ .../Hadrons/Modules/MScalarSUN/TrKinetic.hpp | 10 ++--- extras/Hadrons/Modules/MScalarSUN/TrMag.cc | 12 ++++++ extras/Hadrons/Modules/MScalarSUN/TrMag.hpp | 10 ++--- extras/Hadrons/Modules/MScalarSUN/TrPhi.cc | 12 ++++++ extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp | 10 ++--- .../Hadrons/Modules/MScalarSUN/TransProj.cc | 12 ++++++ .../Hadrons/Modules/MScalarSUN/TransProj.hpp | 10 ++--- extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc | 12 ++++++ .../Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 10 ++--- extras/Hadrons/Modules/MSink/Point.cc | 9 +++++ extras/Hadrons/Modules/MSink/Point.hpp | 4 +- extras/Hadrons/Modules/MSink/Smear.cc | 8 ++++ extras/Hadrons/Modules/MSink/Smear.hpp | 2 +- .../Modules/MSolver/LocalCoherenceLanczos.cc | 9 +++++ .../Modules/MSolver/LocalCoherenceLanczos.hpp | 8 +--- extras/Hadrons/Modules/MSolver/RBPrecCG.cc | 9 +++++ extras/Hadrons/Modules/MSolver/RBPrecCG.hpp | 6 +-- extras/Hadrons/Modules/MSource/Point.cc | 9 +++++ extras/Hadrons/Modules/MSource/Point.hpp | 4 +- .../Hadrons/Modules/MSource/SeqConserved.cc | 8 ++++ .../Hadrons/Modules/MSource/SeqConserved.hpp | 2 +- extras/Hadrons/Modules/MSource/SeqGamma.cc | 8 ++++ extras/Hadrons/Modules/MSource/SeqGamma.hpp | 2 +- extras/Hadrons/Modules/MSource/Wall.cc | 8 ++++ extras/Hadrons/Modules/MSource/Wall.hpp | 2 +- extras/Hadrons/Modules/MSource/Z2.cc | 9 +++++ extras/Hadrons/Modules/MSource/Z2.hpp | 4 +- .../Modules/MUtilities/TestSeqConserved.cc | 8 ++++ .../Modules/MUtilities/TestSeqConserved.hpp | 2 +- .../Modules/MUtilities/TestSeqGamma.cc | 8 ++++ .../Modules/MUtilities/TestSeqGamma.hpp | 2 +- .../templates/Module_in_NS.hpp.template | 2 +- .../templates/Module_tmp_in_NS.hpp.template | 2 +- extras/Hadrons/make_module_inst.sh | 27 ++++++++++++++ extras/Hadrons/modules.inc | 35 +++++++++++++++++- 81 files changed, 467 insertions(+), 152 deletions(-) create mode 100644 extras/Hadrons/Modules/MAction/DWF.cc create mode 100644 extras/Hadrons/Modules/MAction/Wilson.cc create mode 100644 extras/Hadrons/Modules/MAction/WilsonClover.cc create mode 100644 extras/Hadrons/Modules/MAction/ZMobiusDWF.cc create mode 100644 extras/Hadrons/Modules/MContraction/Baryon.cc create mode 100644 extras/Hadrons/Modules/MContraction/DiscLoop.cc create mode 100644 extras/Hadrons/Modules/MContraction/Gamma3pt.cc create mode 100644 extras/Hadrons/Modules/MContraction/Meson.cc create mode 100644 extras/Hadrons/Modules/MContraction/WardIdentity.cc create mode 100644 extras/Hadrons/Modules/MFermion/GaugeProp.cc create mode 100644 extras/Hadrons/Modules/MIO/LoadBinary.cc create mode 100644 extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc create mode 100644 extras/Hadrons/Modules/MIO/LoadEigenPack.cc create mode 100644 extras/Hadrons/Modules/MLoop/NoiseLoop.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/Div.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/EMT.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TrMag.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TrPhi.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TransProj.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc create mode 100644 extras/Hadrons/Modules/MSink/Point.cc create mode 100644 extras/Hadrons/Modules/MSink/Smear.cc create mode 100644 extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc create mode 100644 extras/Hadrons/Modules/MSolver/RBPrecCG.cc create mode 100644 extras/Hadrons/Modules/MSource/Point.cc create mode 100644 extras/Hadrons/Modules/MSource/SeqConserved.cc create mode 100644 extras/Hadrons/Modules/MSource/SeqGamma.cc create mode 100644 extras/Hadrons/Modules/MSource/Wall.cc create mode 100644 extras/Hadrons/Modules/MSource/Z2.cc create mode 100644 extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc create mode 100644 extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc create mode 100755 extras/Hadrons/make_module_inst.sh diff --git a/extras/Hadrons/Application.hpp b/extras/Hadrons/Application.hpp index 0254f2fc..8cd15433 100644 --- a/extras/Hadrons/Application.hpp +++ b/extras/Hadrons/Application.hpp @@ -31,7 +31,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include -#include +#include BEGIN_HADRONS_NAMESPACE diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 583f1111..9229a01c 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -35,32 +35,7 @@ See the full license in the file "LICENSE" in the top level distribution directo BEGIN_HADRONS_NAMESPACE // module registration macros -#define MODULE_REGISTER(mod, base)\ -class mod: public base\ -{\ -public:\ - typedef base Base;\ - using Base::Base;\ - virtual std::string getRegisteredName(void)\ - {\ - return std::string(#mod);\ - }\ -};\ -class mod##ModuleRegistrar\ -{\ -public:\ - mod##ModuleRegistrar(void)\ - {\ - ModuleFactory &modFac = ModuleFactory::getInstance();\ - modFac.registerBuilder(#mod, [&](const std::string name)\ - {\ - return std::unique_ptr(new mod(name));\ - });\ - }\ -};\ -static mod##ModuleRegistrar mod##ModuleRegistrarInstance; - -#define MODULE_REGISTER_NS(mod, base, ns)\ +#define MODULE_REGISTER(mod, base, ns)\ class mod: public base\ {\ public:\ @@ -85,6 +60,10 @@ public:\ };\ static ns##mod##ModuleRegistrar ns##mod##ModuleRegistrarInstance; +#define MODULE_REGISTER_TMP(mod, base, ns)\ +extern template class base;\ +MODULE_REGISTER(mod, ARG(base), ns); + #define ARG(...) __VA_ARGS__ #define MACRO_REDIRECT(arg1, arg2, arg3, macro, ...) macro @@ -144,6 +123,12 @@ MACRO_REDIRECT(__VA_ARGS__, envTmpLat5, envTmpLat4)(__VA_ARGS__) if (env().getGrid()->IsBoss())\ {\ ResultWriter _writer(RESULT_FILE_NAME(ioStem));\ + std::string _basename = basename(ioStem);\ + \ + if (!mkdir(_basename))\ + {\ + HADRON_ERROR(Io, "cannot create directory '" + _basename + "'");\ + }\ write(_writer, name, result);\ } diff --git a/extras/Hadrons/Modules.hpp b/extras/Hadrons/Modules.hpp index 528faecd..cdd94c35 100644 --- a/extras/Hadrons/Modules.hpp +++ b/extras/Hadrons/Modules.hpp @@ -1,33 +1,3 @@ -/************************************************************************************* - -Grid physics library, www.github.com/paboyle/Grid - -Source file: extras/Hadrons/Modules.hpp - -Copyright (C) 2015-2018 - -Author: Antonin Portelli -Author: Guido Cossu -Author: Lanny91 -Author: pretidav - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -See the full license in the file "LICENSE" in the top level distribution directory -*************************************************************************************/ -/* END LEGAL */ #include #include #include diff --git a/extras/Hadrons/Modules/MAction/DWF.cc b/extras/Hadrons/Modules/MAction/DWF.cc new file mode 100644 index 00000000..2037238a --- /dev/null +++ b/extras/Hadrons/Modules/MAction/DWF.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MAction; + +template class Grid::Hadrons::MAction::TDWF; + diff --git a/extras/Hadrons/Modules/MAction/DWF.hpp b/extras/Hadrons/Modules/MAction/DWF.hpp index 4dfd06cf..6be35a8a 100644 --- a/extras/Hadrons/Modules/MAction/DWF.hpp +++ b/extras/Hadrons/Modules/MAction/DWF.hpp @@ -72,7 +72,8 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(DWF, TDWF, MAction); +extern template class TDWF; +MODULE_REGISTER_TMP(DWF, TDWF, MAction); /****************************************************************************** * DWF template implementation * diff --git a/extras/Hadrons/Modules/MAction/Wilson.cc b/extras/Hadrons/Modules/MAction/Wilson.cc new file mode 100644 index 00000000..10526241 --- /dev/null +++ b/extras/Hadrons/Modules/MAction/Wilson.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MAction; + +template class Grid::Hadrons::MAction::TWilson; + diff --git a/extras/Hadrons/Modules/MAction/Wilson.hpp b/extras/Hadrons/Modules/MAction/Wilson.hpp index 6467b3ee..5508b6b8 100644 --- a/extras/Hadrons/Modules/MAction/Wilson.hpp +++ b/extras/Hadrons/Modules/MAction/Wilson.hpp @@ -70,7 +70,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Wilson, TWilson, MAction); +MODULE_REGISTER_TMP(Wilson, TWilson, MAction); /****************************************************************************** * TWilson template implementation * diff --git a/extras/Hadrons/Modules/MAction/WilsonClover.cc b/extras/Hadrons/Modules/MAction/WilsonClover.cc new file mode 100644 index 00000000..d0f90f26 --- /dev/null +++ b/extras/Hadrons/Modules/MAction/WilsonClover.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MAction; + +template class Grid::Hadrons::MAction::TWilsonClover; + diff --git a/extras/Hadrons/Modules/MAction/WilsonClover.hpp b/extras/Hadrons/Modules/MAction/WilsonClover.hpp index 2967931c..a93a0136 100644 --- a/extras/Hadrons/Modules/MAction/WilsonClover.hpp +++ b/extras/Hadrons/Modules/MAction/WilsonClover.hpp @@ -74,7 +74,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(WilsonClover, TWilsonClover, MAction); +MODULE_REGISTER_TMP(WilsonClover, TWilsonClover, MAction); /****************************************************************************** * TWilsonClover template implementation * diff --git a/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc b/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc new file mode 100644 index 00000000..b5be7d9b --- /dev/null +++ b/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MAction; + +template class Grid::Hadrons::MAction::TZMobiusDWF; + diff --git a/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp b/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp index 518b88f2..58a6bb1a 100644 --- a/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp +++ b/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp @@ -72,7 +72,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(ZMobiusDWF, TZMobiusDWF, MAction); +MODULE_REGISTER_TMP(ZMobiusDWF, TZMobiusDWF, MAction); /****************************************************************************** * TZMobiusDWF implementation * diff --git a/extras/Hadrons/Modules/MContraction/Baryon.cc b/extras/Hadrons/Modules/MContraction/Baryon.cc new file mode 100644 index 00000000..7015e899 --- /dev/null +++ b/extras/Hadrons/Modules/MContraction/Baryon.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MContraction; + +template class Grid::Hadrons::MContraction::TBaryon; + diff --git a/extras/Hadrons/Modules/MContraction/Baryon.hpp b/extras/Hadrons/Modules/MContraction/Baryon.hpp index f3bf360d..87691e7b 100644 --- a/extras/Hadrons/Modules/MContraction/Baryon.hpp +++ b/extras/Hadrons/Modules/MContraction/Baryon.hpp @@ -79,7 +79,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Baryon, ARG(TBaryon), MContraction); +MODULE_REGISTER_TMP(Baryon, ARG(TBaryon), MContraction); /****************************************************************************** * TBaryon implementation * diff --git a/extras/Hadrons/Modules/MContraction/DiscLoop.cc b/extras/Hadrons/Modules/MContraction/DiscLoop.cc new file mode 100644 index 00000000..257d7765 --- /dev/null +++ b/extras/Hadrons/Modules/MContraction/DiscLoop.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MContraction; + +template class Grid::Hadrons::MContraction::TDiscLoop; + diff --git a/extras/Hadrons/Modules/MContraction/DiscLoop.hpp b/extras/Hadrons/Modules/MContraction/DiscLoop.hpp index 4a30963f..1c872f0a 100644 --- a/extras/Hadrons/Modules/MContraction/DiscLoop.hpp +++ b/extras/Hadrons/Modules/MContraction/DiscLoop.hpp @@ -76,7 +76,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(DiscLoop, TDiscLoop, MContraction); +MODULE_REGISTER_TMP(DiscLoop, TDiscLoop, MContraction); /****************************************************************************** * TDiscLoop implementation * diff --git a/extras/Hadrons/Modules/MContraction/Gamma3pt.cc b/extras/Hadrons/Modules/MContraction/Gamma3pt.cc new file mode 100644 index 00000000..c4886223 --- /dev/null +++ b/extras/Hadrons/Modules/MContraction/Gamma3pt.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MContraction; + +template class Grid::Hadrons::MContraction::TGamma3pt; + diff --git a/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp b/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp index b615cd7b..2b4b88a7 100644 --- a/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp +++ b/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp @@ -107,7 +107,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Gamma3pt, ARG(TGamma3pt), MContraction); +MODULE_REGISTER_TMP(Gamma3pt, ARG(TGamma3pt), MContraction); /****************************************************************************** * TGamma3pt implementation * diff --git a/extras/Hadrons/Modules/MContraction/Meson.cc b/extras/Hadrons/Modules/MContraction/Meson.cc new file mode 100644 index 00000000..a1c6a742 --- /dev/null +++ b/extras/Hadrons/Modules/MContraction/Meson.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MContraction; + +template class Grid::Hadrons::MContraction::TMeson; + diff --git a/extras/Hadrons/Modules/MContraction/Meson.hpp b/extras/Hadrons/Modules/MContraction/Meson.hpp index 5d27c526..f75e55dc 100644 --- a/extras/Hadrons/Modules/MContraction/Meson.hpp +++ b/extras/Hadrons/Modules/MContraction/Meson.hpp @@ -102,7 +102,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Meson, ARG(TMeson), MContraction); +MODULE_REGISTER_TMP(Meson, ARG(TMeson), MContraction); /****************************************************************************** * TMeson implementation * diff --git a/extras/Hadrons/Modules/MContraction/WardIdentity.cc b/extras/Hadrons/Modules/MContraction/WardIdentity.cc new file mode 100644 index 00000000..cd188e46 --- /dev/null +++ b/extras/Hadrons/Modules/MContraction/WardIdentity.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MContraction; + +template class Grid::Hadrons::MContraction::TWardIdentity; + diff --git a/extras/Hadrons/Modules/MContraction/WardIdentity.hpp b/extras/Hadrons/Modules/MContraction/WardIdentity.hpp index 2801d88c..3b9a1449 100644 --- a/extras/Hadrons/Modules/MContraction/WardIdentity.hpp +++ b/extras/Hadrons/Modules/MContraction/WardIdentity.hpp @@ -84,7 +84,7 @@ private: unsigned int Ls_; }; -MODULE_REGISTER_NS(WardIdentity, TWardIdentity, MContraction); +MODULE_REGISTER_TMP(WardIdentity, TWardIdentity, MContraction); /****************************************************************************** * TWardIdentity implementation * diff --git a/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp b/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp index 9d8ada98..84edc366 100644 --- a/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp +++ b/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp @@ -109,7 +109,7 @@ protected:\ /* execution */ \ virtual void execute(void);\ };\ -MODULE_REGISTER_NS(modname, T##modname, MContraction); +MODULE_REGISTER(modname, T##modname, MContraction); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MFermion/GaugeProp.cc b/extras/Hadrons/Modules/MFermion/GaugeProp.cc new file mode 100644 index 00000000..888b86f1 --- /dev/null +++ b/extras/Hadrons/Modules/MFermion/GaugeProp.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MFermion; + +template class Grid::Hadrons::MFermion::TGaugeProp; + diff --git a/extras/Hadrons/Modules/MFermion/GaugeProp.hpp b/extras/Hadrons/Modules/MFermion/GaugeProp.hpp index 45b9de6c..e85acecb 100644 --- a/extras/Hadrons/Modules/MFermion/GaugeProp.hpp +++ b/extras/Hadrons/Modules/MFermion/GaugeProp.hpp @@ -95,7 +95,7 @@ private: SolverFn *solver_{nullptr}; }; -MODULE_REGISTER_NS(GaugeProp, TGaugeProp, MFermion); +MODULE_REGISTER_TMP(GaugeProp, TGaugeProp, MFermion); /****************************************************************************** * TGaugeProp implementation * ******************************************************************************/ diff --git a/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp b/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp index 508145bc..07274544 100644 --- a/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp +++ b/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp @@ -65,9 +65,9 @@ public: void execute(void); }; -//MODULE_REGISTER_NS(FundtoAdjoint, TFundtoHirep, MGauge); -//MODULE_REGISTER_NS(FundtoTwoIndexSym, TFundtoHirep, MGauge); -//MODULE_REGISTER_NS(FundtoTwoIndexAsym, TFundtoHirep, MGauge); +//MODULE_REGISTER_TMP(FundtoAdjoint, TFundtoHirep, MGauge); +//MODULE_REGISTER_TMP(FundtoTwoIndexSym, TFundtoHirep, MGauge); +//MODULE_REGISTER_TMP(FundtoTwoIndexAsym, TFundtoHirep, MGauge); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MGauge/Random.hpp b/extras/Hadrons/Modules/MGauge/Random.hpp index 51a08dbb..ddc81fc1 100644 --- a/extras/Hadrons/Modules/MGauge/Random.hpp +++ b/extras/Hadrons/Modules/MGauge/Random.hpp @@ -57,7 +57,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Random, TRandom, MGauge); +MODULE_REGISTER(Random, TRandom, MGauge); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MGauge/StochEm.hpp b/extras/Hadrons/Modules/MGauge/StochEm.hpp index 9e2ba1fb..aa7fa51f 100644 --- a/extras/Hadrons/Modules/MGauge/StochEm.hpp +++ b/extras/Hadrons/Modules/MGauge/StochEm.hpp @@ -70,7 +70,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(StochEm, TStochEm, MGauge); +MODULE_REGISTER(StochEm, TStochEm, MGauge); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MGauge/Unit.hpp b/extras/Hadrons/Modules/MGauge/Unit.hpp index d6ce5a6b..bd0faa25 100644 --- a/extras/Hadrons/Modules/MGauge/Unit.hpp +++ b/extras/Hadrons/Modules/MGauge/Unit.hpp @@ -57,7 +57,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Unit, TUnit, MGauge); +MODULE_REGISTER(Unit, TUnit, MGauge); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MIO/LoadBinary.cc b/extras/Hadrons/Modules/MIO/LoadBinary.cc new file mode 100644 index 00000000..4eb76ee1 --- /dev/null +++ b/extras/Hadrons/Modules/MIO/LoadBinary.cc @@ -0,0 +1,13 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MIO; + +template class Grid::Hadrons::MIO::TLoadBinary; +template class Grid::Hadrons::MIO::TLoadBinary>; +template class Grid::Hadrons::MIO::TLoadBinary>; +template class Grid::Hadrons::MIO::TLoadBinary>; +template class Grid::Hadrons::MIO::TLoadBinary>; +template class Grid::Hadrons::MIO::TLoadBinary>; + diff --git a/extras/Hadrons/Modules/MIO/LoadBinary.hpp b/extras/Hadrons/Modules/MIO/LoadBinary.hpp index d9a8b5f8..f14be5fb 100644 --- a/extras/Hadrons/Modules/MIO/LoadBinary.hpp +++ b/extras/Hadrons/Modules/MIO/LoadBinary.hpp @@ -71,12 +71,12 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(LoadBinary, TLoadBinary, MIO); -MODULE_REGISTER_NS(LoadBinaryScalarSU2, TLoadBinary>, MIO); -MODULE_REGISTER_NS(LoadBinaryScalarSU3, TLoadBinary>, MIO); -MODULE_REGISTER_NS(LoadBinaryScalarSU4, TLoadBinary>, MIO); -MODULE_REGISTER_NS(LoadBinaryScalarSU5, TLoadBinary>, MIO); -MODULE_REGISTER_NS(LoadBinaryScalarSU6, TLoadBinary>, MIO); +MODULE_REGISTER_TMP(LoadBinary, TLoadBinary, MIO); +MODULE_REGISTER_TMP(LoadBinaryScalarSU2, TLoadBinary>, MIO); +MODULE_REGISTER_TMP(LoadBinaryScalarSU3, TLoadBinary>, MIO); +MODULE_REGISTER_TMP(LoadBinaryScalarSU4, TLoadBinary>, MIO); +MODULE_REGISTER_TMP(LoadBinaryScalarSU5, TLoadBinary>, MIO); +MODULE_REGISTER_TMP(LoadBinaryScalarSU6, TLoadBinary>, MIO); /****************************************************************************** * TLoadBinary implementation * diff --git a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc new file mode 100644 index 00000000..60637566 --- /dev/null +++ b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MIO; + +template class Grid::Hadrons::MIO::TLoadCoarseEigenPack>; + diff --git a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp index b88844f4..609e5ed4 100644 --- a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp @@ -73,8 +73,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(LoadCoarseFermionEigenPack, - ARG(TLoadCoarseEigenPack>), MIO); +MODULE_REGISTER_TMP(LoadCoarseFermionEigenPack, ARG(TLoadCoarseEigenPack>), MIO); /****************************************************************************** * TLoadCoarseEigenPack implementation * diff --git a/extras/Hadrons/Modules/MIO/LoadEigenPack.cc b/extras/Hadrons/Modules/MIO/LoadEigenPack.cc new file mode 100644 index 00000000..1ed0254d --- /dev/null +++ b/extras/Hadrons/Modules/MIO/LoadEigenPack.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MIO; + +template class Grid::Hadrons::MIO::TLoadEigenPack>; + diff --git a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp index 5d62b53d..8a3b40e7 100644 --- a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp @@ -68,7 +68,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(LoadFermionEigenPack, TLoadEigenPack>, MIO); +MODULE_REGISTER_TMP(LoadFermionEigenPack, TLoadEigenPack>, MIO); /****************************************************************************** * TLoadEigenPack implementation * diff --git a/extras/Hadrons/Modules/MIO/LoadNersc.hpp b/extras/Hadrons/Modules/MIO/LoadNersc.hpp index d6742e1e..309edad2 100644 --- a/extras/Hadrons/Modules/MIO/LoadNersc.hpp +++ b/extras/Hadrons/Modules/MIO/LoadNersc.hpp @@ -62,7 +62,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(LoadNersc, TLoadNersc, MIO); +MODULE_REGISTER(LoadNersc, TLoadNersc, MIO); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MLoop/NoiseLoop.cc b/extras/Hadrons/Modules/MLoop/NoiseLoop.cc new file mode 100644 index 00000000..96707f19 --- /dev/null +++ b/extras/Hadrons/Modules/MLoop/NoiseLoop.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MLoop; + +template class Grid::Hadrons::MLoop::TNoiseLoop; + diff --git a/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp b/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp index e61bf163..588c63da 100644 --- a/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp +++ b/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp @@ -82,7 +82,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(NoiseLoop, TNoiseLoop, MLoop); +MODULE_REGISTER_TMP(NoiseLoop, TNoiseLoop, MLoop); /****************************************************************************** * TNoiseLoop implementation * diff --git a/extras/Hadrons/Modules/MScalar/ChargedProp.hpp b/extras/Hadrons/Modules/MScalar/ChargedProp.hpp index 4d43aec2..72a40cad 100644 --- a/extras/Hadrons/Modules/MScalar/ChargedProp.hpp +++ b/extras/Hadrons/Modules/MScalar/ChargedProp.hpp @@ -80,7 +80,7 @@ private: std::vector phase_; }; -MODULE_REGISTER_NS(ChargedProp, TChargedProp, MScalar); +MODULE_REGISTER(ChargedProp, TChargedProp, MScalar); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MScalar/FreeProp.hpp b/extras/Hadrons/Modules/MScalar/FreeProp.hpp index df17f44e..bf7823e6 100644 --- a/extras/Hadrons/Modules/MScalar/FreeProp.hpp +++ b/extras/Hadrons/Modules/MScalar/FreeProp.hpp @@ -70,7 +70,7 @@ private: bool freePropDone_; }; -MODULE_REGISTER_NS(FreeProp, TFreeProp, MScalar); +MODULE_REGISTER(FreeProp, TFreeProp, MScalar); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.cc b/extras/Hadrons/Modules/MScalarSUN/Div.cc new file mode 100644 index 00000000..1045b04a --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/Div.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TDiv>; +template class Grid::Hadrons::MScalarSUN::TDiv>; +template class Grid::Hadrons::MScalarSUN::TDiv>; +template class Grid::Hadrons::MScalarSUN::TDiv>; +template class Grid::Hadrons::MScalarSUN::TDiv>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.hpp b/extras/Hadrons/Modules/MScalarSUN/Div.hpp index 0ecb1dbe..9b30866c 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Div.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Div.hpp @@ -76,11 +76,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(DivSU2, TDiv>, MScalarSUN); -MODULE_REGISTER_NS(DivSU3, TDiv>, MScalarSUN); -MODULE_REGISTER_NS(DivSU4, TDiv>, MScalarSUN); -MODULE_REGISTER_NS(DivSU5, TDiv>, MScalarSUN); -MODULE_REGISTER_NS(DivSU6, TDiv>, MScalarSUN); +MODULE_REGISTER_TMP(DivSU2, TDiv>, MScalarSUN); +MODULE_REGISTER_TMP(DivSU3, TDiv>, MScalarSUN); +MODULE_REGISTER_TMP(DivSU4, TDiv>, MScalarSUN); +MODULE_REGISTER_TMP(DivSU5, TDiv>, MScalarSUN); +MODULE_REGISTER_TMP(DivSU6, TDiv>, MScalarSUN); /****************************************************************************** * TDiv implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.cc b/extras/Hadrons/Modules/MScalarSUN/EMT.cc new file mode 100644 index 00000000..0d5d652f --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TEMT>; +template class Grid::Hadrons::MScalarSUN::TEMT>; +template class Grid::Hadrons::MScalarSUN::TEMT>; +template class Grid::Hadrons::MScalarSUN::TEMT>; +template class Grid::Hadrons::MScalarSUN::TEMT>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp index 8c1239df..445f3445 100644 --- a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp @@ -74,11 +74,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(EMTSU2, TEMT>, MScalarSUN); -MODULE_REGISTER_NS(EMTSU3, TEMT>, MScalarSUN); -MODULE_REGISTER_NS(EMTSU4, TEMT>, MScalarSUN); -MODULE_REGISTER_NS(EMTSU5, TEMT>, MScalarSUN); -MODULE_REGISTER_NS(EMTSU6, TEMT>, MScalarSUN); +MODULE_REGISTER_TMP(EMTSU2, TEMT>, MScalarSUN); +MODULE_REGISTER_TMP(EMTSU3, TEMT>, MScalarSUN); +MODULE_REGISTER_TMP(EMTSU4, TEMT>, MScalarSUN); +MODULE_REGISTER_TMP(EMTSU5, TEMT>, MScalarSUN); +MODULE_REGISTER_TMP(EMTSU6, TEMT>, MScalarSUN); /****************************************************************************** * TEMT implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc new file mode 100644 index 00000000..339bd9a8 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TShiftProbe>; +template class Grid::Hadrons::MScalarSUN::TShiftProbe>; +template class Grid::Hadrons::MScalarSUN::TShiftProbe>; +template class Grid::Hadrons::MScalarSUN::TShiftProbe>; +template class Grid::Hadrons::MScalarSUN::TShiftProbe>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp index 8d52327e..41b8c553 100644 --- a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp @@ -79,11 +79,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(ShiftProbeSU2, TShiftProbe>, MScalarSUN); -MODULE_REGISTER_NS(ShiftProbeSU3, TShiftProbe>, MScalarSUN); -MODULE_REGISTER_NS(ShiftProbeSU4, TShiftProbe>, MScalarSUN); -MODULE_REGISTER_NS(ShiftProbeSU5, TShiftProbe>, MScalarSUN); -MODULE_REGISTER_NS(ShiftProbeSU6, TShiftProbe>, MScalarSUN); +MODULE_REGISTER_TMP(ShiftProbeSU2, TShiftProbe>, MScalarSUN); +MODULE_REGISTER_TMP(ShiftProbeSU3, TShiftProbe>, MScalarSUN); +MODULE_REGISTER_TMP(ShiftProbeSU4, TShiftProbe>, MScalarSUN); +MODULE_REGISTER_TMP(ShiftProbeSU5, TShiftProbe>, MScalarSUN); +MODULE_REGISTER_TMP(ShiftProbeSU6, TShiftProbe>, MScalarSUN); /****************************************************************************** * TShiftProbe implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc new file mode 100644 index 00000000..8c959dca --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTrKinetic>; +template class Grid::Hadrons::MScalarSUN::TTrKinetic>; +template class Grid::Hadrons::MScalarSUN::TTrKinetic>; +template class Grid::Hadrons::MScalarSUN::TTrKinetic>; +template class Grid::Hadrons::MScalarSUN::TTrKinetic>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp index f1b520de..e448b61e 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp @@ -76,11 +76,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(TrKineticSU2, TTrKinetic>, MScalarSUN); -MODULE_REGISTER_NS(TrKineticSU3, TTrKinetic>, MScalarSUN); -MODULE_REGISTER_NS(TrKineticSU4, TTrKinetic>, MScalarSUN); -MODULE_REGISTER_NS(TrKineticSU5, TTrKinetic>, MScalarSUN); -MODULE_REGISTER_NS(TrKineticSU6, TTrKinetic>, MScalarSUN); +MODULE_REGISTER_TMP(TrKineticSU2, TTrKinetic>, MScalarSUN); +MODULE_REGISTER_TMP(TrKineticSU3, TTrKinetic>, MScalarSUN); +MODULE_REGISTER_TMP(TrKineticSU4, TTrKinetic>, MScalarSUN); +MODULE_REGISTER_TMP(TrKineticSU5, TTrKinetic>, MScalarSUN); +MODULE_REGISTER_TMP(TrKineticSU6, TTrKinetic>, MScalarSUN); /****************************************************************************** * TTrKinetic implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/TrMag.cc b/extras/Hadrons/Modules/MScalarSUN/TrMag.cc new file mode 100644 index 00000000..3be84f92 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TrMag.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTrMag>; +template class Grid::Hadrons::MScalarSUN::TTrMag>; +template class Grid::Hadrons::MScalarSUN::TTrMag>; +template class Grid::Hadrons::MScalarSUN::TTrMag>; +template class Grid::Hadrons::MScalarSUN::TTrMag>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp b/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp index 879951d5..efadc16f 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp @@ -76,11 +76,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(TrMagSU2, TTrMag>, MScalarSUN); -MODULE_REGISTER_NS(TrMagSU3, TTrMag>, MScalarSUN); -MODULE_REGISTER_NS(TrMagSU4, TTrMag>, MScalarSUN); -MODULE_REGISTER_NS(TrMagSU5, TTrMag>, MScalarSUN); -MODULE_REGISTER_NS(TrMagSU6, TTrMag>, MScalarSUN); +MODULE_REGISTER_TMP(TrMagSU2, TTrMag>, MScalarSUN); +MODULE_REGISTER_TMP(TrMagSU3, TTrMag>, MScalarSUN); +MODULE_REGISTER_TMP(TrMagSU4, TTrMag>, MScalarSUN); +MODULE_REGISTER_TMP(TrMagSU5, TTrMag>, MScalarSUN); +MODULE_REGISTER_TMP(TrMagSU6, TTrMag>, MScalarSUN); /****************************************************************************** * TTrMag implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc b/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc new file mode 100644 index 00000000..58c6df75 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTrPhi>; +template class Grid::Hadrons::MScalarSUN::TTrPhi>; +template class Grid::Hadrons::MScalarSUN::TTrPhi>; +template class Grid::Hadrons::MScalarSUN::TTrPhi>; +template class Grid::Hadrons::MScalarSUN::TTrPhi>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp index aa98bfb3..3f43a7b1 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp @@ -76,11 +76,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(TrPhiSU2, TTrPhi>, MScalarSUN); -MODULE_REGISTER_NS(TrPhiSU3, TTrPhi>, MScalarSUN); -MODULE_REGISTER_NS(TrPhiSU4, TTrPhi>, MScalarSUN); -MODULE_REGISTER_NS(TrPhiSU5, TTrPhi>, MScalarSUN); -MODULE_REGISTER_NS(TrPhiSU6, TTrPhi>, MScalarSUN); +MODULE_REGISTER_TMP(TrPhiSU2, TTrPhi>, MScalarSUN); +MODULE_REGISTER_TMP(TrPhiSU3, TTrPhi>, MScalarSUN); +MODULE_REGISTER_TMP(TrPhiSU4, TTrPhi>, MScalarSUN); +MODULE_REGISTER_TMP(TrPhiSU5, TTrPhi>, MScalarSUN); +MODULE_REGISTER_TMP(TrPhiSU6, TTrPhi>, MScalarSUN); /****************************************************************************** * TTrPhi implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/TransProj.cc b/extras/Hadrons/Modules/MScalarSUN/TransProj.cc new file mode 100644 index 00000000..09a469ea --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TransProj.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTransProj>; +template class Grid::Hadrons::MScalarSUN::TTransProj>; +template class Grid::Hadrons::MScalarSUN::TTransProj>; +template class Grid::Hadrons::MScalarSUN::TTransProj>; +template class Grid::Hadrons::MScalarSUN::TTransProj>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp b/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp index 4532b4ab..b525b053 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp @@ -77,11 +77,11 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(TransProjSU2, TTransProj>, MScalarSUN); -MODULE_REGISTER_NS(TransProjSU3, TTransProj>, MScalarSUN); -MODULE_REGISTER_NS(TransProjSU4, TTransProj>, MScalarSUN); -MODULE_REGISTER_NS(TransProjSU5, TTransProj>, MScalarSUN); -MODULE_REGISTER_NS(TransProjSU6, TTransProj>, MScalarSUN); +MODULE_REGISTER_TMP(TransProjSU2, TTransProj>, MScalarSUN); +MODULE_REGISTER_TMP(TransProjSU3, TTransProj>, MScalarSUN); +MODULE_REGISTER_TMP(TransProjSU4, TTransProj>, MScalarSUN); +MODULE_REGISTER_TMP(TransProjSU5, TTransProj>, MScalarSUN); +MODULE_REGISTER_TMP(TransProjSU6, TTransProj>, MScalarSUN); /****************************************************************************** * TTransProj implementation * diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc new file mode 100644 index 00000000..6e009bb6 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc @@ -0,0 +1,12 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTwoPoint>; +template class Grid::Hadrons::MScalarSUN::TTwoPoint>; +template class Grid::Hadrons::MScalarSUN::TTwoPoint>; +template class Grid::Hadrons::MScalarSUN::TTwoPoint>; +template class Grid::Hadrons::MScalarSUN::TTwoPoint>; + diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index 5ec56714..e50e23d7 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -87,11 +87,11 @@ private: std::vector> mom_; }; -MODULE_REGISTER_NS(TwoPointSU2, TTwoPoint>, MScalarSUN); -MODULE_REGISTER_NS(TwoPointSU3, TTwoPoint>, MScalarSUN); -MODULE_REGISTER_NS(TwoPointSU4, TTwoPoint>, MScalarSUN); -MODULE_REGISTER_NS(TwoPointSU5, TTwoPoint>, MScalarSUN); -MODULE_REGISTER_NS(TwoPointSU6, TTwoPoint>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointSU2, TTwoPoint>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointSU3, TTwoPoint>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointSU4, TTwoPoint>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointSU5, TTwoPoint>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointSU6, TTwoPoint>, MScalarSUN); /****************************************************************************** * TTwoPoint implementation * diff --git a/extras/Hadrons/Modules/MSink/Point.cc b/extras/Hadrons/Modules/MSink/Point.cc new file mode 100644 index 00000000..fbb3b2f2 --- /dev/null +++ b/extras/Hadrons/Modules/MSink/Point.cc @@ -0,0 +1,9 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSink; + +template class Grid::Hadrons::MSink::TPoint; +template class Grid::Hadrons::MSink::TPoint; + diff --git a/extras/Hadrons/Modules/MSink/Point.hpp b/extras/Hadrons/Modules/MSink/Point.hpp index ee824c03..1c14915a 100644 --- a/extras/Hadrons/Modules/MSink/Point.hpp +++ b/extras/Hadrons/Modules/MSink/Point.hpp @@ -72,8 +72,8 @@ private: std::string momphName_; }; -MODULE_REGISTER_NS(Point, TPoint, MSink); -MODULE_REGISTER_NS(ScalarPoint, TPoint, MSink); +MODULE_REGISTER_TMP(Point, TPoint, MSink); +MODULE_REGISTER_TMP(ScalarPoint, TPoint, MSink); /****************************************************************************** * TPoint implementation * diff --git a/extras/Hadrons/Modules/MSink/Smear.cc b/extras/Hadrons/Modules/MSink/Smear.cc new file mode 100644 index 00000000..8ce5f354 --- /dev/null +++ b/extras/Hadrons/Modules/MSink/Smear.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSink; + +template class Grid::Hadrons::MSink::TSmear; + diff --git a/extras/Hadrons/Modules/MSink/Smear.hpp b/extras/Hadrons/Modules/MSink/Smear.hpp index e72dece0..82a21a80 100644 --- a/extras/Hadrons/Modules/MSink/Smear.hpp +++ b/extras/Hadrons/Modules/MSink/Smear.hpp @@ -70,7 +70,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Smear, TSmear, MSink); +MODULE_REGISTER_TMP(Smear, TSmear, MSink); /****************************************************************************** * TSmear implementation * diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc new file mode 100644 index 00000000..64588a5b --- /dev/null +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc @@ -0,0 +1,9 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSolver; + +template class Grid::Hadrons::MSolver::TLocalCoherenceLanczos; +template class Grid::Hadrons::MSolver::TLocalCoherenceLanczos; + diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index 2b7c1049..4695d8e2 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -79,12 +79,8 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(LocalCoherenceLanczos, - ARG(TLocalCoherenceLanczos), - MSolver); -MODULE_REGISTER_NS(ZLocalCoherenceLanczos, - ARG(TLocalCoherenceLanczos), - MSolver); +MODULE_REGISTER_TMP(LocalCoherenceLanczos, ARG(TLocalCoherenceLanczos), MSolver); +MODULE_REGISTER_TMP(ZLocalCoherenceLanczos, ARG(TLocalCoherenceLanczos), MSolver); /****************************************************************************** * TLocalCoherenceLanczos implementation * diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.cc b/extras/Hadrons/Modules/MSolver/RBPrecCG.cc new file mode 100644 index 00000000..4c0aa48e --- /dev/null +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.cc @@ -0,0 +1,9 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSolver; + +template class Grid::Hadrons::MSolver::TRBPrecCG; +template class Grid::Hadrons::MSolver::TRBPrecCG; + diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp index 6e4fbba6..e241161f 100644 --- a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp @@ -79,10 +79,8 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(RBPrecCG, - ARG(TRBPrecCG), MSolver); -MODULE_REGISTER_NS(ZRBPrecCG, - ARG(TRBPrecCG), MSolver); +MODULE_REGISTER_TMP(RBPrecCG, ARG(TRBPrecCG), MSolver); +MODULE_REGISTER_TMP(ZRBPrecCG, ARG(TRBPrecCG), MSolver); /****************************************************************************** * TRBPrecCG template implementation * diff --git a/extras/Hadrons/Modules/MSource/Point.cc b/extras/Hadrons/Modules/MSource/Point.cc new file mode 100644 index 00000000..f16c43d2 --- /dev/null +++ b/extras/Hadrons/Modules/MSource/Point.cc @@ -0,0 +1,9 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSource; + +template class Grid::Hadrons::MSource::TPoint; +template class Grid::Hadrons::MSource::TPoint; + diff --git a/extras/Hadrons/Modules/MSource/Point.hpp b/extras/Hadrons/Modules/MSource/Point.hpp index ac6df252..50297a8b 100644 --- a/extras/Hadrons/Modules/MSource/Point.hpp +++ b/extras/Hadrons/Modules/MSource/Point.hpp @@ -79,8 +79,8 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(Point, TPoint, MSource); -MODULE_REGISTER_NS(ScalarPoint, TPoint, MSource); +MODULE_REGISTER_TMP(Point, TPoint, MSource); +MODULE_REGISTER_TMP(ScalarPoint, TPoint, MSource); /****************************************************************************** * TPoint template implementation * diff --git a/extras/Hadrons/Modules/MSource/SeqConserved.cc b/extras/Hadrons/Modules/MSource/SeqConserved.cc new file mode 100644 index 00000000..9db92c98 --- /dev/null +++ b/extras/Hadrons/Modules/MSource/SeqConserved.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSource; + +template class Grid::Hadrons::MSource::TSeqConserved; + diff --git a/extras/Hadrons/Modules/MSource/SeqConserved.hpp b/extras/Hadrons/Modules/MSource/SeqConserved.hpp index d7780528..a5d21995 100644 --- a/extras/Hadrons/Modules/MSource/SeqConserved.hpp +++ b/extras/Hadrons/Modules/MSource/SeqConserved.hpp @@ -103,7 +103,7 @@ private: std::string SeqmomphName_; }; -MODULE_REGISTER_NS(SeqConserved, TSeqConserved, MSource); +MODULE_REGISTER_TMP(SeqConserved, TSeqConserved, MSource); /****************************************************************************** diff --git a/extras/Hadrons/Modules/MSource/SeqGamma.cc b/extras/Hadrons/Modules/MSource/SeqGamma.cc new file mode 100644 index 00000000..744ad837 --- /dev/null +++ b/extras/Hadrons/Modules/MSource/SeqGamma.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSource; + +template class Grid::Hadrons::MSource::TSeqGamma; + diff --git a/extras/Hadrons/Modules/MSource/SeqGamma.hpp b/extras/Hadrons/Modules/MSource/SeqGamma.hpp index 40eda29f..9d99b5b3 100644 --- a/extras/Hadrons/Modules/MSource/SeqGamma.hpp +++ b/extras/Hadrons/Modules/MSource/SeqGamma.hpp @@ -90,7 +90,7 @@ private: std::string momphName_, tName_; }; -MODULE_REGISTER_NS(SeqGamma, TSeqGamma, MSource); +MODULE_REGISTER_TMP(SeqGamma, TSeqGamma, MSource); /****************************************************************************** * TSeqGamma implementation * diff --git a/extras/Hadrons/Modules/MSource/Wall.cc b/extras/Hadrons/Modules/MSource/Wall.cc new file mode 100644 index 00000000..42e19a8f --- /dev/null +++ b/extras/Hadrons/Modules/MSource/Wall.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSource; + +template class Grid::Hadrons::MSource::TWall; + diff --git a/extras/Hadrons/Modules/MSource/Wall.hpp b/extras/Hadrons/Modules/MSource/Wall.hpp index 5853b11a..9494e739 100644 --- a/extras/Hadrons/Modules/MSource/Wall.hpp +++ b/extras/Hadrons/Modules/MSource/Wall.hpp @@ -84,7 +84,7 @@ private: std::string momphName_, tName_; }; -MODULE_REGISTER_NS(Wall, TWall, MSource); +MODULE_REGISTER_TMP(Wall, TWall, MSource); /****************************************************************************** * TWall implementation * diff --git a/extras/Hadrons/Modules/MSource/Z2.cc b/extras/Hadrons/Modules/MSource/Z2.cc new file mode 100644 index 00000000..e655e253 --- /dev/null +++ b/extras/Hadrons/Modules/MSource/Z2.cc @@ -0,0 +1,9 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MSource; + +template class Grid::Hadrons::MSource::TZ2; +template class Grid::Hadrons::MSource::TZ2; + diff --git a/extras/Hadrons/Modules/MSource/Z2.hpp b/extras/Hadrons/Modules/MSource/Z2.hpp index 4414e37f..065d5fdf 100644 --- a/extras/Hadrons/Modules/MSource/Z2.hpp +++ b/extras/Hadrons/Modules/MSource/Z2.hpp @@ -85,8 +85,8 @@ private: std::string tName_; }; -MODULE_REGISTER_NS(Z2, TZ2, MSource); -MODULE_REGISTER_NS(ScalarZ2, TZ2, MSource); +MODULE_REGISTER_TMP(Z2, TZ2, MSource); +MODULE_REGISTER_TMP(ScalarZ2, TZ2, MSource); /****************************************************************************** * TZ2 template implementation * diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc new file mode 100644 index 00000000..94d2c946 --- /dev/null +++ b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MUtilities; + +template class Grid::Hadrons::MUtilities::TTestSeqConserved; + diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp index 6ee1e3c2..bf2370eb 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp +++ b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp @@ -88,7 +88,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(TestSeqConserved, TTestSeqConserved, MUtilities); +MODULE_REGISTER_TMP(TestSeqConserved, TTestSeqConserved, MUtilities); /****************************************************************************** * TTestSeqConserved implementation * diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc new file mode 100644 index 00000000..59635c5d --- /dev/null +++ b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc @@ -0,0 +1,8 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MUtilities; + +template class Grid::Hadrons::MUtilities::TTestSeqGamma; + diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp index df35d887..9284a638 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp +++ b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp @@ -72,7 +72,7 @@ protected: virtual void execute(void); }; -MODULE_REGISTER_NS(TestSeqGamma, TTestSeqGamma, MUtilities); +MODULE_REGISTER_TMP(TestSeqGamma, TTestSeqGamma, MUtilities); /****************************************************************************** * TTestSeqGamma implementation * diff --git a/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template b/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template index ea77b12a..f645d046 100644 --- a/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template +++ b/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template @@ -35,7 +35,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(___FILEBASENAME___, T___FILEBASENAME___, ___NAMESPACE___); +MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___, ___NAMESPACE___); END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template b/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template index b79c0ad3..48df254b 100644 --- a/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template +++ b/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template @@ -36,7 +36,7 @@ public: virtual void execute(void); }; -MODULE_REGISTER_NS(___FILEBASENAME___, T___FILEBASENAME___, ___NAMESPACE___); +MODULE_REGISTER_TMP(___FILEBASENAME___, T___FILEBASENAME___, ___NAMESPACE___); /****************************************************************************** * T___FILEBASENAME___ implementation * diff --git a/extras/Hadrons/make_module_inst.sh b/extras/Hadrons/make_module_inst.sh new file mode 100755 index 00000000..32ead3f0 --- /dev/null +++ b/extras/Hadrons/make_module_inst.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +for m in `find Modules -name '*.hpp' -type f -print`; do + echo "====== ${m}" + CCFILE=`echo $m | sed -E s/\.hpp/.cc/g` + NS=`echo $m | awk -F '/' '{print $2}'` + NMOD=`grep -E 'MODULE_REGISTER_TMP.+<.+>.?' $m | wc -l` + if [ ! -e ${CCFILE} ] && (( NMOD != 0 )); then + echo "#include " >> ${CCFILE} + echo "" >> ${CCFILE} + echo "using namespace Grid;" >> ${CCFILE} + echo "using namespace Hadrons;" >> ${CCFILE} + echo "using namespace ${NS};" >> ${CCFILE} + echo "" >> ${CCFILE} + for i in `grep -E 'MODULE_REGISTER_TMP.+<.+>.?' $m | sed -E 's/ +//g'` + do + TMPARG=`echo ${i} | grep -oE 'ARG\(.+>\)' | sed -E 's/^ARG\(//g' | sed -E 's/\)$//g'` + SUB=`echo ${i} | sed -E 's/ARG\(.+>\)/@arg@/g' | sed -E 's/,/|/g'` + SUB=`echo ${SUB} | sed -E 's/.+\(//g' | sed -E 's/\);//g'` + SUB=`echo ${SUB} | sed -E "s/@arg@/${TMPARG}/g"` + NAME=`echo ${SUB} | awk -F '|' '{print $1}'` + TYPE=`echo ${SUB} | awk -F '|' '{print $2}'` + echo "template class Grid::Hadrons::${NS}::${TYPE};" >> ${CCFILE} + done + echo "" >> ${CCFILE} + fi +done \ No newline at end of file diff --git a/extras/Hadrons/modules.inc b/extras/Hadrons/modules.inc index 5932cc89..ec954bbe 100644 --- a/extras/Hadrons/modules.inc +++ b/extras/Hadrons/modules.inc @@ -1,14 +1,47 @@ modules_cc =\ Modules/MContraction/WeakHamiltonianEye.cc \ + Modules/MContraction/Baryon.cc \ + Modules/MContraction/Meson.cc \ Modules/MContraction/WeakNeutral4ptDisc.cc \ Modules/MContraction/WeakHamiltonianNonEye.cc \ + Modules/MContraction/WardIdentity.cc \ + Modules/MContraction/DiscLoop.cc \ + Modules/MContraction/Gamma3pt.cc \ + Modules/MFermion/GaugeProp.cc \ + Modules/MSource/Point.cc \ + Modules/MSource/Wall.cc \ + Modules/MSource/SeqConserved.cc \ + Modules/MSource/SeqGamma.cc \ + Modules/MSource/Z2.cc \ + Modules/MSink/Point.cc \ + Modules/MSink/Smear.cc \ + Modules/MSolver/RBPrecCG.cc \ + Modules/MSolver/LocalCoherenceLanczos.cc \ Modules/MGauge/Unit.cc \ Modules/MGauge/StochEm.cc \ Modules/MGauge/Random.cc \ Modules/MGauge/FundtoHirep.cc \ + Modules/MUtilities/TestSeqGamma.cc \ + Modules/MUtilities/TestSeqConserved.cc \ + Modules/MLoop/NoiseLoop.cc \ Modules/MScalar/FreeProp.cc \ Modules/MScalar/ChargedProp.cc \ - Modules/MIO/LoadNersc.cc + Modules/MAction/Wilson.cc \ + Modules/MAction/ZMobiusDWF.cc \ + Modules/MAction/WilsonClover.cc \ + Modules/MAction/DWF.cc \ + Modules/MScalarSUN/TrPhi.cc \ + Modules/MScalarSUN/TrMag.cc \ + Modules/MScalarSUN/TrKinetic.cc \ + Modules/MScalarSUN/EMT.cc \ + Modules/MScalarSUN/ShiftProbe.cc \ + Modules/MScalarSUN/TransProj.cc \ + Modules/MScalarSUN/TwoPoint.cc \ + Modules/MScalarSUN/Div.cc \ + Modules/MIO/LoadEigenPack.cc \ + Modules/MIO/LoadBinary.cc \ + Modules/MIO/LoadNersc.cc \ + Modules/MIO/LoadCoarseEigenPack.cc modules_hpp =\ Modules/MContraction/Baryon.hpp \ From ce7720e221fcdff4ba5a8f6824fcd1b129a7b623 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 17:36:20 +0100 Subject: [PATCH 053/126] Hadrons: copyright update --- extras/Hadrons/Modules.hpp | 30 +++++++++++++++++++ extras/Hadrons/Modules/MAction/DWF.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MAction/Wilson.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MAction/WilsonClover.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MAction/ZMobiusDWF.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MContraction/Baryon.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MContraction/DiscLoop.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MContraction/Gamma3pt.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MContraction/Meson.cc | 27 +++++++++++++++++ .../Modules/MContraction/WardIdentity.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MFermion/GaugeProp.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MGauge/FundtoHirep.cc | 6 ++-- extras/Hadrons/Modules/MGauge/StochEm.cc | 1 + extras/Hadrons/Modules/MIO/LoadBinary.cc | 27 +++++++++++++++++ .../Modules/MIO/LoadCoarseEigenPack.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MIO/LoadEigenPack.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MLoop/NoiseLoop.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MScalarSUN/Div.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MScalarSUN/EMT.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MScalarSUN/ShiftProbe.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MScalarSUN/TrKinetic.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MScalarSUN/TrMag.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MScalarSUN/TrPhi.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MScalarSUN/TransProj.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSink/Point.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSink/Point.hpp | 1 + extras/Hadrons/Modules/MSink/Smear.cc | 27 +++++++++++++++++ .../Modules/MSolver/LocalCoherenceLanczos.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSolver/RBPrecCG.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSource/Point.cc | 27 +++++++++++++++++ .../Hadrons/Modules/MSource/SeqConserved.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSource/SeqGamma.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSource/Wall.cc | 27 +++++++++++++++++ extras/Hadrons/Modules/MSource/Z2.cc | 27 +++++++++++++++++ .../Modules/MUtilities/TestSeqConserved.cc | 27 +++++++++++++++++ .../Modules/MUtilities/TestSeqGamma.cc | 27 +++++++++++++++++ 37 files changed, 927 insertions(+), 2 deletions(-) diff --git a/extras/Hadrons/Modules.hpp b/extras/Hadrons/Modules.hpp index cdd94c35..528faecd 100644 --- a/extras/Hadrons/Modules.hpp +++ b/extras/Hadrons/Modules.hpp @@ -1,3 +1,33 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules.hpp + +Copyright (C) 2015-2018 + +Author: Antonin Portelli +Author: Guido Cossu +Author: Lanny91 +Author: pretidav + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +See the full license in the file "LICENSE" in the top level distribution directory +*************************************************************************************/ +/* END LEGAL */ #include #include #include diff --git a/extras/Hadrons/Modules/MAction/DWF.cc b/extras/Hadrons/Modules/MAction/DWF.cc index 2037238a..ae518018 100644 --- a/extras/Hadrons/Modules/MAction/DWF.cc +++ b/extras/Hadrons/Modules/MAction/DWF.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MAction/DWF.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MAction/Wilson.cc b/extras/Hadrons/Modules/MAction/Wilson.cc index 10526241..11924d5a 100644 --- a/extras/Hadrons/Modules/MAction/Wilson.cc +++ b/extras/Hadrons/Modules/MAction/Wilson.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MAction/Wilson.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MAction/WilsonClover.cc b/extras/Hadrons/Modules/MAction/WilsonClover.cc index d0f90f26..77099044 100644 --- a/extras/Hadrons/Modules/MAction/WilsonClover.cc +++ b/extras/Hadrons/Modules/MAction/WilsonClover.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MAction/WilsonClover.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc b/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc index b5be7d9b..7a49c120 100644 --- a/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc +++ b/extras/Hadrons/Modules/MAction/ZMobiusDWF.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MAction/ZMobiusDWF.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MContraction/Baryon.cc b/extras/Hadrons/Modules/MContraction/Baryon.cc index 7015e899..7daf5008 100644 --- a/extras/Hadrons/Modules/MContraction/Baryon.cc +++ b/extras/Hadrons/Modules/MContraction/Baryon.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MContraction/Baryon.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MContraction/DiscLoop.cc b/extras/Hadrons/Modules/MContraction/DiscLoop.cc index 257d7765..8c7a72ee 100644 --- a/extras/Hadrons/Modules/MContraction/DiscLoop.cc +++ b/extras/Hadrons/Modules/MContraction/DiscLoop.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MContraction/DiscLoop.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MContraction/Gamma3pt.cc b/extras/Hadrons/Modules/MContraction/Gamma3pt.cc index c4886223..13e911bb 100644 --- a/extras/Hadrons/Modules/MContraction/Gamma3pt.cc +++ b/extras/Hadrons/Modules/MContraction/Gamma3pt.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MContraction/Gamma3pt.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MContraction/Meson.cc b/extras/Hadrons/Modules/MContraction/Meson.cc index a1c6a742..3b880705 100644 --- a/extras/Hadrons/Modules/MContraction/Meson.cc +++ b/extras/Hadrons/Modules/MContraction/Meson.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MContraction/Meson.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MContraction/WardIdentity.cc b/extras/Hadrons/Modules/MContraction/WardIdentity.cc index cd188e46..8b5cc2e3 100644 --- a/extras/Hadrons/Modules/MContraction/WardIdentity.cc +++ b/extras/Hadrons/Modules/MContraction/WardIdentity.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MContraction/WardIdentity.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MFermion/GaugeProp.cc b/extras/Hadrons/Modules/MFermion/GaugeProp.cc index 888b86f1..8db69495 100644 --- a/extras/Hadrons/Modules/MFermion/GaugeProp.cc +++ b/extras/Hadrons/Modules/MFermion/GaugeProp.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MFermion/GaugeProp.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MGauge/FundtoHirep.cc b/extras/Hadrons/Modules/MGauge/FundtoHirep.cc index ba8e9330..824ee8c8 100644 --- a/extras/Hadrons/Modules/MGauge/FundtoHirep.cc +++ b/extras/Hadrons/Modules/MGauge/FundtoHirep.cc @@ -4,9 +4,11 @@ Grid physics library, www.github.com/paboyle/Grid Source file: extras/Hadrons/Modules/MGauge/FundtoHirep.cc -Copyright (C) 2015 -Copyright (C) 2016 +Copyright (C) 2015-2018 +Author: Antonin Portelli +Author: Guido Cossu +Author: pretidav 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 diff --git a/extras/Hadrons/Modules/MGauge/StochEm.cc b/extras/Hadrons/Modules/MGauge/StochEm.cc index cfbd28ef..7b07557e 100644 --- a/extras/Hadrons/Modules/MGauge/StochEm.cc +++ b/extras/Hadrons/Modules/MGauge/StochEm.cc @@ -7,6 +7,7 @@ Source file: extras/Hadrons/Modules/MGauge/StochEm.cc Copyright (C) 2015-2018 Author: Antonin Portelli +Author: Vera Guelpers 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 diff --git a/extras/Hadrons/Modules/MIO/LoadBinary.cc b/extras/Hadrons/Modules/MIO/LoadBinary.cc index 4eb76ee1..f04df9df 100644 --- a/extras/Hadrons/Modules/MIO/LoadBinary.cc +++ b/extras/Hadrons/Modules/MIO/LoadBinary.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MIO/LoadBinary.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc index 60637566..0ed7643c 100644 --- a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc +++ b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MIO/LoadEigenPack.cc b/extras/Hadrons/Modules/MIO/LoadEigenPack.cc index 1ed0254d..5b7aebc3 100644 --- a/extras/Hadrons/Modules/MIO/LoadEigenPack.cc +++ b/extras/Hadrons/Modules/MIO/LoadEigenPack.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MIO/LoadEigenPack.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MLoop/NoiseLoop.cc b/extras/Hadrons/Modules/MLoop/NoiseLoop.cc index 96707f19..5c510afd 100644 --- a/extras/Hadrons/Modules/MLoop/NoiseLoop.cc +++ b/extras/Hadrons/Modules/MLoop/NoiseLoop.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MLoop/NoiseLoop.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.cc b/extras/Hadrons/Modules/MScalarSUN/Div.cc index 1045b04a..6a2e366d 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Div.cc +++ b/extras/Hadrons/Modules/MScalarSUN/Div.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/Div.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.cc b/extras/Hadrons/Modules/MScalarSUN/EMT.cc index 0d5d652f..7f8ca16d 100644 --- a/extras/Hadrons/Modules/MScalarSUN/EMT.cc +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/EMT.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc index 339bd9a8..30320667 100644 --- a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/ShiftProbe.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc index 8c959dca..8d377f21 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc +++ b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/TrKinetic.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/TrMag.cc b/extras/Hadrons/Modules/MScalarSUN/TrMag.cc index 3be84f92..29897abc 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrMag.cc +++ b/extras/Hadrons/Modules/MScalarSUN/TrMag.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/TrMag.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc b/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc index 58c6df75..e1fcb8e5 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc +++ b/extras/Hadrons/Modules/MScalarSUN/TrPhi.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/TrPhi.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/TransProj.cc b/extras/Hadrons/Modules/MScalarSUN/TransProj.cc index 09a469ea..0fb230bb 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TransProj.cc +++ b/extras/Hadrons/Modules/MScalarSUN/TransProj.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/TransProj.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc index 6e009bb6..840cc02a 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/TwoPoint.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSink/Point.cc b/extras/Hadrons/Modules/MSink/Point.cc index fbb3b2f2..127c4c74 100644 --- a/extras/Hadrons/Modules/MSink/Point.cc +++ b/extras/Hadrons/Modules/MSink/Point.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSink/Point.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSink/Point.hpp b/extras/Hadrons/Modules/MSink/Point.hpp index 1c14915a..a4a28b97 100644 --- a/extras/Hadrons/Modules/MSink/Point.hpp +++ b/extras/Hadrons/Modules/MSink/Point.hpp @@ -7,6 +7,7 @@ Source file: extras/Hadrons/Modules/MSink/Point.hpp Copyright (C) 2015-2018 Author: Antonin Portelli +Author: Guido Cossu Author: Lanny91 This program is free software; you can redistribute it and/or modify diff --git a/extras/Hadrons/Modules/MSink/Smear.cc b/extras/Hadrons/Modules/MSink/Smear.cc index 8ce5f354..ff250140 100644 --- a/extras/Hadrons/Modules/MSink/Smear.cc +++ b/extras/Hadrons/Modules/MSink/Smear.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSink/Smear.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc index 64588a5b..5bddce95 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.cc b/extras/Hadrons/Modules/MSolver/RBPrecCG.cc index 4c0aa48e..867c6c5d 100644 --- a/extras/Hadrons/Modules/MSolver/RBPrecCG.cc +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSolver/RBPrecCG.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSource/Point.cc b/extras/Hadrons/Modules/MSource/Point.cc index f16c43d2..5e49af2a 100644 --- a/extras/Hadrons/Modules/MSource/Point.cc +++ b/extras/Hadrons/Modules/MSource/Point.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSource/Point.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSource/SeqConserved.cc b/extras/Hadrons/Modules/MSource/SeqConserved.cc index 9db92c98..35b6ef37 100644 --- a/extras/Hadrons/Modules/MSource/SeqConserved.cc +++ b/extras/Hadrons/Modules/MSource/SeqConserved.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSource/SeqConserved.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSource/SeqGamma.cc b/extras/Hadrons/Modules/MSource/SeqGamma.cc index 744ad837..ce4f3dd0 100644 --- a/extras/Hadrons/Modules/MSource/SeqGamma.cc +++ b/extras/Hadrons/Modules/MSource/SeqGamma.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSource/SeqGamma.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSource/Wall.cc b/extras/Hadrons/Modules/MSource/Wall.cc index 42e19a8f..9b293232 100644 --- a/extras/Hadrons/Modules/MSource/Wall.cc +++ b/extras/Hadrons/Modules/MSource/Wall.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSource/Wall.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MSource/Z2.cc b/extras/Hadrons/Modules/MSource/Z2.cc index e655e253..9644c6fd 100644 --- a/extras/Hadrons/Modules/MSource/Z2.cc +++ b/extras/Hadrons/Modules/MSource/Z2.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MSource/Z2.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc index 94d2c946..99beac71 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc +++ b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MUtilities/TestSeqConserved.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc index 59635c5d..f53d9f85 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc +++ b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc @@ -1,3 +1,30 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MUtilities/TestSeqGamma.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 using namespace Grid; From b61292f73570fc66df39b3122e4f201e315e9267 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 17:36:43 +0100 Subject: [PATCH 054/126] Hadrons: recursive mkdir function --- extras/Hadrons/Global.cc | 51 +++++++++++++++++++++++++++++++++++++++ extras/Hadrons/Global.hpp | 6 ++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/extras/Hadrons/Global.cc b/extras/Hadrons/Global.cc index 32060460..22193770 100644 --- a/extras/Hadrons/Global.cc +++ b/extras/Hadrons/Global.cc @@ -92,3 +92,54 @@ const std::string Hadrons::resultFileExt = "h5"; #else const std::string Hadrons::resultFileExt = "xml"; #endif + +// recursive mkdir ///////////////////////////////////////////////////////////// +int Hadrons::mkdir(const std::string dirName) +{ + if (access(dirName.c_str(), R_OK|W_OK|X_OK)) + { + mode_t mode755; + char tmp[MAX_PATH_LENGTH]; + char *p = NULL; + size_t len; + + mode755 = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; + + snprintf(tmp, sizeof(tmp), "%s", dirName.c_str()); + len = strlen(tmp); + if(tmp[len - 1] == '/') + { + tmp[len - 1] = 0; + } + for(p = tmp + 1; *p; p++) + { + if(*p == '/') + { + *p = 0; + ::mkdir(tmp, mode755); + *p = '/'; + } + } + + return ::mkdir(tmp, mode755); + } + else + { + return 0; + } +} + +std::string Hadrons::basename(const std::string &s) +{ + constexpr char sep = '/'; + size_t i = s.rfind(sep, s.length()); + + if (i != std::string::npos) + { + return s.substr(i+1, s.length() - i); + } + else + { + return s; + } +} diff --git a/extras/Hadrons/Global.hpp b/extras/Hadrons/Global.hpp index 12b9a029..cf3a4409 100644 --- a/extras/Hadrons/Global.hpp +++ b/extras/Hadrons/Global.hpp @@ -187,8 +187,12 @@ typedef XmlWriter ResultWriter; #define RESULT_FILE_NAME(name) \ name + "." + std::to_string(vm().getTrajectory()) + "." + resultFileExt -// default Schur convention +// recursive mkdir +#define MAX_PATH_LENGTH 512u +int mkdir(const std::string dirName); +std::string basename(const std::string &s); +// default Schur convention #ifndef HADRONS_DEFAULT_SCHUR #define HADRONS_DEFAULT_SCHUR DiagTwo #endif From 2fa2b0e0b12450212f1d4aa2eb94207c4d76a40c Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 17:57:17 +0100 Subject: [PATCH 055/126] Hadrons: Application header does not include all the modules --- extras/Hadrons/Application.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/Application.hpp b/extras/Hadrons/Application.hpp index 8cd15433..0254f2fc 100644 --- a/extras/Hadrons/Application.hpp +++ b/extras/Hadrons/Application.hpp @@ -31,7 +31,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include -#include +#include BEGIN_HADRONS_NAMESPACE From 6764362237233ce83ea571f35dbeca6834fc8c9b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 18:45:39 +0100 Subject: [PATCH 056/126] Hadrons: automatic directory creation fix --- extras/Hadrons/Global.cc | 17 ++++++++++++++++- extras/Hadrons/Global.hpp | 1 + extras/Hadrons/Module.hpp | 12 +++++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/extras/Hadrons/Global.cc b/extras/Hadrons/Global.cc index 22193770..82bd8eba 100644 --- a/extras/Hadrons/Global.cc +++ b/extras/Hadrons/Global.cc @@ -96,7 +96,7 @@ const std::string Hadrons::resultFileExt = "xml"; // recursive mkdir ///////////////////////////////////////////////////////////// int Hadrons::mkdir(const std::string dirName) { - if (access(dirName.c_str(), R_OK|W_OK|X_OK)) + if (!dirName.empty() and access(dirName.c_str(), R_OK|W_OK|X_OK)) { mode_t mode755; char tmp[MAX_PATH_LENGTH]; @@ -143,3 +143,18 @@ std::string Hadrons::basename(const std::string &s) return s; } } + +std::string Hadrons::dirname(const std::string &s) +{ + constexpr char sep = '/'; + size_t i = s.rfind(sep, s.length()); + + if (i != std::string::npos) + { + return s.substr(0, i); + } + else + { + return ""; + } +} diff --git a/extras/Hadrons/Global.hpp b/extras/Hadrons/Global.hpp index cf3a4409..5e729579 100644 --- a/extras/Hadrons/Global.hpp +++ b/extras/Hadrons/Global.hpp @@ -191,6 +191,7 @@ name + "." + std::to_string(vm().getTrajectory()) + "." + resultFileExt #define MAX_PATH_LENGTH 512u int mkdir(const std::string dirName); std::string basename(const std::string &s); +std::string dirname(const std::string &s); // default Schur convention #ifndef HADRONS_DEFAULT_SCHUR diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 9229a01c..656aacef 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -122,14 +122,16 @@ MACRO_REDIRECT(__VA_ARGS__, envTmpLat5, envTmpLat4)(__VA_ARGS__) #define saveResult(ioStem, name, result)\ if (env().getGrid()->IsBoss())\ {\ - ResultWriter _writer(RESULT_FILE_NAME(ioStem));\ - std::string _basename = basename(ioStem);\ + std::string _dirname = dirname(ioStem);\ \ - if (!mkdir(_basename))\ + if (mkdir(_dirname))\ {\ - HADRON_ERROR(Io, "cannot create directory '" + _basename + "'");\ + HADRON_ERROR(Io, "cannot create directory '" + _dirname + "'");\ + }\ + {\ + ResultWriter _writer(RESULT_FILE_NAME(ioStem));\ + write(_writer, name, result);\ }\ - write(_writer, name, result);\ } /****************************************************************************** From af84fd65bb953c553ab69771a804e54227600799 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 22:46:17 +0100 Subject: [PATCH 057/126] Hadrons: missing dependency message improvement --- extras/Hadrons/VirtualMachine.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extras/Hadrons/VirtualMachine.cc b/extras/Hadrons/VirtualMachine.cc index a96df622..49096d92 100644 --- a/extras/Hadrons/VirtualMachine.cc +++ b/extras/Hadrons/VirtualMachine.cc @@ -306,9 +306,10 @@ void VirtualMachine::makeModuleGraph(void) if (min < 0) { - HADRON_ERROR(Definition, "object with address " - + std::to_string(in) - + " is not produced by any module"); + HADRON_ERROR(Definition, "dependency '" + + env().getObjectName(in) + "' (address " + + std::to_string(in) + + ") is not produced by any module"); } else { From 7c4533797f20c5ba1a5b3700d0c8adf5253d27a0 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 23 Apr 2018 22:46:39 +0100 Subject: [PATCH 058/126] Hadrons: scalar SU(N) EMT improvement term optional --- extras/Hadrons/Modules/MScalarSUN/EMT.hpp | 24 ++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp index 445f3445..1059c934 100644 --- a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp @@ -99,7 +99,10 @@ std::vector TEMT::getInput(void) for (unsigned int nu = mu; nu < env().getNd(); ++nu) { in.push_back(varName(par().kinetic, mu, nu)); - in.push_back(varName(par().improvement, mu, nu)); + if (!par().improvement.empty()) + { + in.push_back(varName(par().improvement, mu, nu)); + } } in.push_back(varName(par().phiPow, 2)); in.push_back(varName(par().phiPow, 4)); @@ -140,11 +143,17 @@ void TEMT::execute(void) LOG(Message) << "Computing energy-momentum tensor" << std::endl; LOG(Message) << " kinetic terms: '" << par().kinetic << "'" << std::endl; LOG(Message) << " tr(phi^n): '" << par().phiPow << "'" << std::endl; - LOG(Message) << " improvement: '" << par().improvement << "'" << std::endl; + if (!par().improvement.empty()) + { + LOG(Message) << " improvement: '" << par().improvement << "'" << std::endl; + } LOG(Message) << " m^2= " << par().m2 << std::endl; LOG(Message) << " lambda= " << par().lambda << std::endl; LOG(Message) << " g= " << par().g << std::endl; - LOG(Message) << " xi= " << par().xi << std::endl; + if (!par().improvement.empty()) + { + LOG(Message) << " xi= " << par().xi << std::endl; + } const unsigned int N = SImpl::Group::Dimension; auto &trphi2 = envGet(ComplexField, varName(par().phiPow, 2)); @@ -163,9 +172,14 @@ void TEMT::execute(void) { auto &out = envGet(ComplexField, varName(getName(), mu, nu)); auto &trkin = envGet(ComplexField, varName(par().kinetic, mu, nu)); - auto &imp = envGet(ComplexField, varName(par().improvement, mu, nu)); + + out = 2.*trkin; + if (!par().improvement.empty()) + { + auto &imp = envGet(ComplexField, varName(par().improvement, mu, nu)); - out = 2.*trkin + par().xi*imp; + out += par().xi*imp; + } if (mu == nu) { out -= sumkin + par().m2*trphi2 + par().lambda*trphi4; From a1be53332956d4eb074632ef10a1449a0aac582e Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 24 Apr 2018 01:19:53 -0700 Subject: [PATCH 059/126] Corrected Flop count in Benchmark su3 and expanded the Wilson flow output --- benchmarks/Benchmark_su3.cc | 4 ++-- lib/qcd/smearing/WilsonFlow.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index 628ad5bd..5f088fdc 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -166,7 +166,7 @@ int main (int argc, char ** argv) double time = (stop-start)/Nloop*1000.0; double bytes=3*vol*Nc*Nc*sizeof(Complex); - double flops=Nc*Nc*(8+8+8)*vol; + double flops=Nc*Nc*(6+8+8)*vol; std::cout<::smear(GaugeField& out, const GaugeField& in) const { std::cout << "Time to evolve " << diff.count() << " s\n"; #endif std::cout << GridLogMessage << "[WilsonFlow] Energy density (plaq) : " - << step << " " - << energyDensityPlaquette(step,out) << std::endl; + << step << " " << tau(step) << " " + << energyDensityPlaquette(step,out) << std::endl; if( step % measure_interval == 0){ std::cout << GridLogMessage << "[WilsonFlow] Top. charge : " << step << " " @@ -193,8 +193,8 @@ void WilsonFlow::smear_adaptive(GaugeField& out, const GaugeField& in, Re //std::cout << GridLogMessage << "Evolution time :"<< taus << std::endl; evolve_step_adaptive(out, maxTau); std::cout << GridLogMessage << "[WilsonFlow] Energy density (plaq) : " - << step << " " - << energyDensityPlaquette(out) << std::endl; + << step << " " << taus << " " + << energyDensityPlaquette(out) << std::endl; if( step % measure_interval == 0){ std::cout << GridLogMessage << "[WilsonFlow] Top. charge : " << step << " " From c5b9147b5334be7f7996e8814df6762f0b9ae1e9 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 24 Apr 2018 08:03:57 -0700 Subject: [PATCH 060/126] Correction of a minor bug in the su3 benchmark --- benchmarks/Benchmark_su3.cc | 52 ++++++++++++++++++------------------- lib/cshift/Cshift_mpi.h | 13 +++++++--- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index 5f088fdc..b31af942 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -52,7 +52,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -147,30 +147,30 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); - int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; - - GridCartesian Grid(latt_size,simd_layout,mpi_layout); - GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(std::vector({45,12,81,9})); - - LatticeColourMatrix z(&Grid); random(pRNG,z); - LatticeColourMatrix x(&Grid); random(pRNG,x); - LatticeColourMatrix y(&Grid); random(pRNG,y); - - double start=usecond(); - for(int64_t i=0;i latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); + int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; + + GridCartesian Grid(latt_size,simd_layout,mpi_layout); + GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(std::vector({45,12,81,9})); + + LatticeColourMatrix z(&Grid); random(pRNG,z); + LatticeColourMatrix x(&Grid); random(pRNG,x); + LatticeColourMatrix y(&Grid); random(pRNG,y); + + double start=usecond(); + for(int64_t i=0;i latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -190,7 +189,7 @@ int main (int argc, char ** argv) LatticeColourMatrix x(&Grid); random(pRNG,x); LatticeColourMatrix y(&Grid); random(pRNG,y); - for(int mu=0;mu<=4;mu++){ + for(int mu=0;mu<4;mu++){ double start=usecond(); for(int64_t i=0;i Lattice Cshift(const Lattice &rhs,int dimension if ( !comm_dim ) { - // std::cout << "Cshift_local" < void Cshift_comms_simd(Lattice& ret,const LatticeCheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even); sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd); + //std::cout << "Cshift_comms_simd dim "< void Cshift_comms_simd(Lattice &ret,const Lattice_simd_layout[dimension]; int comm_dim = grid->_processors[dimension] >1 ; + //std::cout << "Cshift_comms_simd dim "<< dimension << " fd "<=0); From b25a59e95e19e419ce487ac901c0bf1ae7717e84 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 17:20:25 +0100 Subject: [PATCH 061/126] Hadrons: mitigation of GCC/Intel compiler bug not generating defaulted destructors --- extras/Hadrons/Modules/MAction/DWF.hpp | 2 +- extras/Hadrons/Modules/MAction/Wilson.hpp | 2 +- extras/Hadrons/Modules/MAction/WilsonClover.hpp | 2 +- extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp | 2 +- extras/Hadrons/Modules/MContraction/Baryon.hpp | 2 +- extras/Hadrons/Modules/MContraction/DiscLoop.hpp | 2 +- extras/Hadrons/Modules/MContraction/Gamma3pt.hpp | 2 +- extras/Hadrons/Modules/MContraction/Meson.hpp | 2 +- extras/Hadrons/Modules/MContraction/WardIdentity.hpp | 2 +- extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp | 2 +- extras/Hadrons/Modules/MFermion/GaugeProp.hpp | 2 +- extras/Hadrons/Modules/MGauge/FundtoHirep.hpp | 2 +- extras/Hadrons/Modules/MGauge/Random.hpp | 2 +- extras/Hadrons/Modules/MGauge/StochEm.hpp | 2 +- extras/Hadrons/Modules/MGauge/Unit.hpp | 2 +- extras/Hadrons/Modules/MIO/LoadBinary.hpp | 2 +- extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp | 2 +- extras/Hadrons/Modules/MIO/LoadEigenPack.hpp | 2 +- extras/Hadrons/Modules/MIO/LoadNersc.hpp | 2 +- extras/Hadrons/Modules/MLoop/NoiseLoop.hpp | 2 +- extras/Hadrons/Modules/MScalar/ChargedProp.hpp | 2 +- extras/Hadrons/Modules/MScalar/FreeProp.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/Div.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/EMT.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp | 4 ++-- extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/TrMag.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/TransProj.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 2 +- extras/Hadrons/Modules/MSink/Point.hpp | 2 +- extras/Hadrons/Modules/MSink/Smear.hpp | 2 +- extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp | 2 +- extras/Hadrons/Modules/MSolver/RBPrecCG.hpp | 2 +- extras/Hadrons/Modules/MSource/Point.hpp | 2 +- extras/Hadrons/Modules/MSource/SeqConserved.hpp | 2 +- extras/Hadrons/Modules/MSource/SeqGamma.hpp | 2 +- extras/Hadrons/Modules/MSource/Wall.hpp | 2 +- extras/Hadrons/Modules/MSource/Z2.hpp | 2 +- extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp | 2 +- extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp | 2 +- 41 files changed, 42 insertions(+), 42 deletions(-) diff --git a/extras/Hadrons/Modules/MAction/DWF.hpp b/extras/Hadrons/Modules/MAction/DWF.hpp index 6be35a8a..f0dda4b0 100644 --- a/extras/Hadrons/Modules/MAction/DWF.hpp +++ b/extras/Hadrons/Modules/MAction/DWF.hpp @@ -61,7 +61,7 @@ public: // constructor TDWF(const std::string name); // destructor - virtual ~TDWF(void) = default; + virtual ~TDWF(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MAction/Wilson.hpp b/extras/Hadrons/Modules/MAction/Wilson.hpp index 5508b6b8..1a119571 100644 --- a/extras/Hadrons/Modules/MAction/Wilson.hpp +++ b/extras/Hadrons/Modules/MAction/Wilson.hpp @@ -59,7 +59,7 @@ public: // constructor TWilson(const std::string name); // destructor - virtual ~TWilson(void) = default; + virtual ~TWilson(void) {}; // dependencies/products virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MAction/WilsonClover.hpp b/extras/Hadrons/Modules/MAction/WilsonClover.hpp index a93a0136..ead3accc 100644 --- a/extras/Hadrons/Modules/MAction/WilsonClover.hpp +++ b/extras/Hadrons/Modules/MAction/WilsonClover.hpp @@ -64,7 +64,7 @@ public: // constructor TWilsonClover(const std::string name); // destructor - virtual ~TWilsonClover(void) = default; + virtual ~TWilsonClover(void) {}; // dependencies/products virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp b/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp index 58a6bb1a..52e65322 100644 --- a/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp +++ b/extras/Hadrons/Modules/MAction/ZMobiusDWF.hpp @@ -62,7 +62,7 @@ public: // constructor TZMobiusDWF(const std::string name); // destructor - virtual ~TZMobiusDWF(void) = default; + virtual ~TZMobiusDWF(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MContraction/Baryon.hpp b/extras/Hadrons/Modules/MContraction/Baryon.hpp index 87691e7b..654706c6 100644 --- a/extras/Hadrons/Modules/MContraction/Baryon.hpp +++ b/extras/Hadrons/Modules/MContraction/Baryon.hpp @@ -68,7 +68,7 @@ public: // constructor TBaryon(const std::string name); // destructor - virtual ~TBaryon(void) = default; + virtual ~TBaryon(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MContraction/DiscLoop.hpp b/extras/Hadrons/Modules/MContraction/DiscLoop.hpp index 1c872f0a..ea3d3d2f 100644 --- a/extras/Hadrons/Modules/MContraction/DiscLoop.hpp +++ b/extras/Hadrons/Modules/MContraction/DiscLoop.hpp @@ -65,7 +65,7 @@ public: // constructor TDiscLoop(const std::string name); // destructor - virtual ~TDiscLoop(void) = default; + virtual ~TDiscLoop(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp b/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp index 2b4b88a7..e30845bc 100644 --- a/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp +++ b/extras/Hadrons/Modules/MContraction/Gamma3pt.hpp @@ -96,7 +96,7 @@ public: // constructor TGamma3pt(const std::string name); // destructor - virtual ~TGamma3pt(void) = default; + virtual ~TGamma3pt(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MContraction/Meson.hpp b/extras/Hadrons/Modules/MContraction/Meson.hpp index f75e55dc..036247e2 100644 --- a/extras/Hadrons/Modules/MContraction/Meson.hpp +++ b/extras/Hadrons/Modules/MContraction/Meson.hpp @@ -90,7 +90,7 @@ public: // constructor TMeson(const std::string name); // destructor - virtual ~TMeson(void) = default; + virtual ~TMeson(void) {}; // dependencies/products virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MContraction/WardIdentity.hpp b/extras/Hadrons/Modules/MContraction/WardIdentity.hpp index 3b9a1449..f1ca6c2b 100644 --- a/extras/Hadrons/Modules/MContraction/WardIdentity.hpp +++ b/extras/Hadrons/Modules/MContraction/WardIdentity.hpp @@ -71,7 +71,7 @@ public: // constructor TWardIdentity(const std::string name); // destructor - virtual ~TWardIdentity(void) = default; + virtual ~TWardIdentity(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp b/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp index 84edc366..507e8cdb 100644 --- a/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp +++ b/extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp @@ -97,7 +97,7 @@ public:\ /* constructor */ \ T##modname(const std::string name);\ /* destructor */ \ - virtual ~T##modname(void) = default;\ + virtual ~T##modname(void) {};\ /* dependency relation */ \ virtual std::vector getInput(void);\ virtual std::vector getOutput(void);\ diff --git a/extras/Hadrons/Modules/MFermion/GaugeProp.hpp b/extras/Hadrons/Modules/MFermion/GaugeProp.hpp index e85acecb..9a359427 100644 --- a/extras/Hadrons/Modules/MFermion/GaugeProp.hpp +++ b/extras/Hadrons/Modules/MFermion/GaugeProp.hpp @@ -81,7 +81,7 @@ public: // constructor TGaugeProp(const std::string name); // destructor - virtual ~TGaugeProp(void) = default; + virtual ~TGaugeProp(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp b/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp index 07274544..3a3a83e5 100644 --- a/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp +++ b/extras/Hadrons/Modules/MGauge/FundtoHirep.hpp @@ -55,7 +55,7 @@ public: // constructor TFundtoHirep(const std::string name); // destructor - virtual ~TFundtoHirep(void) = default; + virtual ~TFundtoHirep(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MGauge/Random.hpp b/extras/Hadrons/Modules/MGauge/Random.hpp index ddc81fc1..13d0e478 100644 --- a/extras/Hadrons/Modules/MGauge/Random.hpp +++ b/extras/Hadrons/Modules/MGauge/Random.hpp @@ -46,7 +46,7 @@ public: // constructor TRandom(const std::string name); // destructor - virtual ~TRandom(void) = default; + virtual ~TRandom(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MGauge/StochEm.hpp b/extras/Hadrons/Modules/MGauge/StochEm.hpp index aa7fa51f..a933afab 100644 --- a/extras/Hadrons/Modules/MGauge/StochEm.hpp +++ b/extras/Hadrons/Modules/MGauge/StochEm.hpp @@ -57,7 +57,7 @@ public: // constructor TStochEm(const std::string name); // destructor - virtual ~TStochEm(void) = default; + virtual ~TStochEm(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MGauge/Unit.hpp b/extras/Hadrons/Modules/MGauge/Unit.hpp index bd0faa25..8bdb7ef3 100644 --- a/extras/Hadrons/Modules/MGauge/Unit.hpp +++ b/extras/Hadrons/Modules/MGauge/Unit.hpp @@ -46,7 +46,7 @@ public: // constructor TUnit(const std::string name); // destructor - virtual ~TUnit(void) = default; + virtual ~TUnit(void) {}; // dependencies/products virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MIO/LoadBinary.hpp b/extras/Hadrons/Modules/MIO/LoadBinary.hpp index f14be5fb..b2070bef 100644 --- a/extras/Hadrons/Modules/MIO/LoadBinary.hpp +++ b/extras/Hadrons/Modules/MIO/LoadBinary.hpp @@ -61,7 +61,7 @@ public: // constructor TLoadBinary(const std::string name); // destructor - virtual ~TLoadBinary(void) = default; + virtual ~TLoadBinary(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp index 609e5ed4..6661f3cc 100644 --- a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp @@ -63,7 +63,7 @@ public: // constructor TLoadCoarseEigenPack(const std::string name); // destructor - virtual ~TLoadCoarseEigenPack(void) = default; + virtual ~TLoadCoarseEigenPack(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp index 8a3b40e7..a95bc51e 100644 --- a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp @@ -58,7 +58,7 @@ public: // constructor TLoadEigenPack(const std::string name); // destructor - virtual ~TLoadEigenPack(void) = default; + virtual ~TLoadEigenPack(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MIO/LoadNersc.hpp b/extras/Hadrons/Modules/MIO/LoadNersc.hpp index 309edad2..11b86eec 100644 --- a/extras/Hadrons/Modules/MIO/LoadNersc.hpp +++ b/extras/Hadrons/Modules/MIO/LoadNersc.hpp @@ -52,7 +52,7 @@ public: // constructor TLoadNersc(const std::string name); // destructor - virtual ~TLoadNersc(void) = default; + virtual ~TLoadNersc(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp b/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp index 588c63da..3ce9353d 100644 --- a/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp +++ b/extras/Hadrons/Modules/MLoop/NoiseLoop.hpp @@ -71,7 +71,7 @@ public: // constructor TNoiseLoop(const std::string name); // destructor - virtual ~TNoiseLoop(void) = default; + virtual ~TNoiseLoop(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalar/ChargedProp.hpp b/extras/Hadrons/Modules/MScalar/ChargedProp.hpp index 72a40cad..549d6154 100644 --- a/extras/Hadrons/Modules/MScalar/ChargedProp.hpp +++ b/extras/Hadrons/Modules/MScalar/ChargedProp.hpp @@ -60,7 +60,7 @@ public: // constructor TChargedProp(const std::string name); // destructor - virtual ~TChargedProp(void) = default; + virtual ~TChargedProp(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalar/FreeProp.hpp b/extras/Hadrons/Modules/MScalar/FreeProp.hpp index bf7823e6..50f4ba52 100644 --- a/extras/Hadrons/Modules/MScalar/FreeProp.hpp +++ b/extras/Hadrons/Modules/MScalar/FreeProp.hpp @@ -56,7 +56,7 @@ public: // constructor TFreeProp(const std::string name); // destructor - virtual ~TFreeProp(void) = default; + virtual ~TFreeProp(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.hpp b/extras/Hadrons/Modules/MScalarSUN/Div.hpp index 9b30866c..4382eb9f 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Div.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Div.hpp @@ -66,7 +66,7 @@ public: // constructor TDiv(const std::string name); // destructor - virtual ~TDiv(void) = default; + virtual ~TDiv(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp index 1059c934..fbc9c62a 100644 --- a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp @@ -64,7 +64,7 @@ public: // constructor TEMT(const std::string name); // destructor - virtual ~TEMT(void) = default; + virtual ~TEMT(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp index 41b8c553..979a340e 100644 --- a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp @@ -69,7 +69,7 @@ public: // constructor TShiftProbe(const std::string name); // destructor - virtual ~TShiftProbe(void) = default; + virtual ~TShiftProbe(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); @@ -159,7 +159,7 @@ void TShiftProbe::execute(void) acc *= Cshift(phi, shift[i].first, shift[i].second); } } - probe = sign*trace(acc); + probe = real(sign*trace(acc)); } END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp index e448b61e..a8c7f521 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp @@ -66,7 +66,7 @@ public: // constructor TTrKinetic(const std::string name); // destructor - virtual ~TTrKinetic(void) = default; + virtual ~TTrKinetic(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp b/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp index efadc16f..ed1a629a 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp @@ -66,7 +66,7 @@ public: // constructor TTrMag(const std::string name); // destructor - virtual ~TTrMag(void) = default; + virtual ~TTrMag(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp index 3f43a7b1..a61c00bc 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp @@ -66,7 +66,7 @@ public: // constructor TTrPhi(const std::string name); // destructor - virtual ~TTrPhi(void) = default; + virtual ~TTrPhi(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp b/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp index b525b053..6c6502fc 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp @@ -66,7 +66,7 @@ public: // constructor TTransProj(const std::string name); // destructor - virtual ~TTransProj(void) = default; + virtual ~TTransProj(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index e50e23d7..27edf370 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -70,7 +70,7 @@ public: // constructor TTwoPoint(const std::string name); // destructor - virtual ~TTwoPoint(void) = default; + virtual ~TTwoPoint(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSink/Point.hpp b/extras/Hadrons/Modules/MSink/Point.hpp index a4a28b97..7617ee78 100644 --- a/extras/Hadrons/Modules/MSink/Point.hpp +++ b/extras/Hadrons/Modules/MSink/Point.hpp @@ -59,7 +59,7 @@ public: // constructor TPoint(const std::string name); // destructor - virtual ~TPoint(void) = default; + virtual ~TPoint(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSink/Smear.hpp b/extras/Hadrons/Modules/MSink/Smear.hpp index 82a21a80..1a46c693 100644 --- a/extras/Hadrons/Modules/MSink/Smear.hpp +++ b/extras/Hadrons/Modules/MSink/Smear.hpp @@ -59,7 +59,7 @@ public: // constructor TSmear(const std::string name); // destructor - virtual ~TSmear(void) = default; + virtual ~TSmear(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index 4695d8e2..b4bad7b5 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -69,7 +69,7 @@ public: // constructor TLocalCoherenceLanczos(const std::string name); // destructor - virtual ~TLocalCoherenceLanczos(void) = default; + virtual ~TLocalCoherenceLanczos(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp index e241161f..f559c4eb 100644 --- a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp @@ -67,7 +67,7 @@ public: // constructor TRBPrecCG(const std::string name); // destructor - virtual ~TRBPrecCG(void) = default; + virtual ~TRBPrecCG(void) {}; // dependencies/products virtual std::vector getInput(void); virtual std::vector getReference(void); diff --git a/extras/Hadrons/Modules/MSource/Point.hpp b/extras/Hadrons/Modules/MSource/Point.hpp index 50297a8b..0898a1a8 100644 --- a/extras/Hadrons/Modules/MSource/Point.hpp +++ b/extras/Hadrons/Modules/MSource/Point.hpp @@ -68,7 +68,7 @@ public: // constructor TPoint(const std::string name); // destructor - virtual ~TPoint(void) = default; + virtual ~TPoint(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSource/SeqConserved.hpp b/extras/Hadrons/Modules/MSource/SeqConserved.hpp index a5d21995..ce9cd4e6 100644 --- a/extras/Hadrons/Modules/MSource/SeqConserved.hpp +++ b/extras/Hadrons/Modules/MSource/SeqConserved.hpp @@ -89,7 +89,7 @@ public: // constructor TSeqConserved(const std::string name); // destructor - virtual ~TSeqConserved(void) = default; + virtual ~TSeqConserved(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSource/SeqGamma.hpp b/extras/Hadrons/Modules/MSource/SeqGamma.hpp index 9d99b5b3..4fe4dd76 100644 --- a/extras/Hadrons/Modules/MSource/SeqGamma.hpp +++ b/extras/Hadrons/Modules/MSource/SeqGamma.hpp @@ -76,7 +76,7 @@ public: // constructor TSeqGamma(const std::string name); // destructor - virtual ~TSeqGamma(void) = default; + virtual ~TSeqGamma(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSource/Wall.hpp b/extras/Hadrons/Modules/MSource/Wall.hpp index 9494e739..f8bec19e 100644 --- a/extras/Hadrons/Modules/MSource/Wall.hpp +++ b/extras/Hadrons/Modules/MSource/Wall.hpp @@ -70,7 +70,7 @@ public: // constructor TWall(const std::string name); // destructor - virtual ~TWall(void) = default; + virtual ~TWall(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MSource/Z2.hpp b/extras/Hadrons/Modules/MSource/Z2.hpp index 065d5fdf..cecff8b0 100644 --- a/extras/Hadrons/Modules/MSource/Z2.hpp +++ b/extras/Hadrons/Modules/MSource/Z2.hpp @@ -71,7 +71,7 @@ public: // constructor TZ2(const std::string name); // destructor - virtual ~TZ2(void) = default; + virtual ~TZ2(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp index bf2370eb..dcd1ba9a 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp +++ b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp @@ -77,7 +77,7 @@ public: // constructor TTestSeqConserved(const std::string name); // destructor - virtual ~TTestSeqConserved(void) = default; + virtual ~TTestSeqConserved(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp index 9284a638..6f2665e4 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp +++ b/extras/Hadrons/Modules/MUtilities/TestSeqGamma.hpp @@ -61,7 +61,7 @@ public: // constructor TTestSeqGamma(const std::string name); // destructor - virtual ~TTestSeqGamma(void) = default; + virtual ~TTestSeqGamma(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); From 325c73d0513968b00fdc28c67f1e5e572c50d847 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 17:55:08 +0100 Subject: [PATCH 062/126] Hadrons: module template update --- .../Modules/templates/Module.cc.template | 39 --------- .../Modules/templates/Module.hpp.template | 40 --------- .../templates/Module_in_NS.hpp.template | 2 +- .../Modules/templates/Module_tmp.hpp.template | 81 ------------------- .../templates/Module_tmp_in_NS.cc.template | 7 ++ .../templates/Module_tmp_in_NS.hpp.template | 2 +- extras/Hadrons/add_module.sh | 35 +++----- extras/Hadrons/add_module_template.sh | 32 +++----- 8 files changed, 35 insertions(+), 203 deletions(-) delete mode 100644 extras/Hadrons/Modules/templates/Module.cc.template delete mode 100644 extras/Hadrons/Modules/templates/Module.hpp.template delete mode 100644 extras/Hadrons/Modules/templates/Module_tmp.hpp.template create mode 100644 extras/Hadrons/Modules/templates/Module_tmp_in_NS.cc.template diff --git a/extras/Hadrons/Modules/templates/Module.cc.template b/extras/Hadrons/Modules/templates/Module.cc.template deleted file mode 100644 index 0c509d6d..00000000 --- a/extras/Hadrons/Modules/templates/Module.cc.template +++ /dev/null @@ -1,39 +0,0 @@ -#include - -using namespace Grid; -using namespace Hadrons; - -/****************************************************************************** -* T___FILEBASENAME___ implementation * -******************************************************************************/ -// constructor ///////////////////////////////////////////////////////////////// -T___FILEBASENAME___::T___FILEBASENAME___(const std::string name) -: Module<___FILEBASENAME___Par>(name) -{} - -// dependencies/products /////////////////////////////////////////////////////// -std::vector T___FILEBASENAME___::getInput(void) -{ - std::vector in; - - return in; -} - -std::vector T___FILEBASENAME___::getOutput(void) -{ - std::vector out = {getName()}; - - return out; -} - -// setup /////////////////////////////////////////////////////////////////////// -void T___FILEBASENAME___::setup(void) -{ - -} - -// execution /////////////////////////////////////////////////////////////////// -void T___FILEBASENAME___::execute(void) -{ - -} diff --git a/extras/Hadrons/Modules/templates/Module.hpp.template b/extras/Hadrons/Modules/templates/Module.hpp.template deleted file mode 100644 index fb43260f..00000000 --- a/extras/Hadrons/Modules/templates/Module.hpp.template +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef Hadrons____FILEBASENAME____hpp_ -#define Hadrons____FILEBASENAME____hpp_ - -#include -#include -#include - -BEGIN_HADRONS_NAMESPACE - -/****************************************************************************** - * ___FILEBASENAME___ * - ******************************************************************************/ -class ___FILEBASENAME___Par: Serializable -{ -public: - GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par, - unsigned int, i); -}; - -class T___FILEBASENAME___: public Module<___FILEBASENAME___Par> -{ -public: - // constructor - T___FILEBASENAME___(const std::string name); - // destructor - virtual ~T___FILEBASENAME___(void) = default; - // dependency relation - virtual std::vector getInput(void); - virtual std::vector getOutput(void); - // setup - virtual void setup(void); - // execution - virtual void execute(void); -}; - -MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___); - -END_HADRONS_NAMESPACE - -#endif // Hadrons____FILEBASENAME____hpp_ diff --git a/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template b/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template index f645d046..b34568c2 100644 --- a/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template +++ b/extras/Hadrons/Modules/templates/Module_in_NS.hpp.template @@ -25,7 +25,7 @@ public: // constructor T___FILEBASENAME___(const std::string name); // destructor - virtual ~T___FILEBASENAME___(void) = default; + virtual ~T___FILEBASENAME___(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/Modules/templates/Module_tmp.hpp.template b/extras/Hadrons/Modules/templates/Module_tmp.hpp.template deleted file mode 100644 index 2ee053a9..00000000 --- a/extras/Hadrons/Modules/templates/Module_tmp.hpp.template +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef Hadrons____FILEBASENAME____hpp_ -#define Hadrons____FILEBASENAME____hpp_ - -#include -#include -#include - -BEGIN_HADRONS_NAMESPACE - -/****************************************************************************** - * ___FILEBASENAME___ * - ******************************************************************************/ -class ___FILEBASENAME___Par: Serializable -{ -public: - GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par, - unsigned int, i); -}; - -template -class T___FILEBASENAME___: public Module<___FILEBASENAME___Par> -{ -public: - // constructor - T___FILEBASENAME___(const std::string name); - // destructor - virtual ~T___FILEBASENAME___(void) = default; - // dependency relation - virtual std::vector getInput(void); - virtual std::vector getOutput(void); - // setup - virtual void setup(void); - // execution - virtual void execute(void); -}; - -MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___); - -/****************************************************************************** - * T___FILEBASENAME___ implementation * - ******************************************************************************/ -// constructor ///////////////////////////////////////////////////////////////// -template -T___FILEBASENAME___::T___FILEBASENAME___(const std::string name) -: Module<___FILEBASENAME___Par>(name) -{} - -// dependencies/products /////////////////////////////////////////////////////// -template -std::vector T___FILEBASENAME___::getInput(void) -{ - std::vector in; - - return in; -} - -template -std::vector T___FILEBASENAME___::getOutput(void) -{ - std::vector out = {getName()}; - - return out; -} - -// setup /////////////////////////////////////////////////////////////////////// -template -void T___FILEBASENAME___::setup(void) -{ - -} - -// execution /////////////////////////////////////////////////////////////////// -template -void T___FILEBASENAME___::execute(void) -{ - -} - -END_HADRONS_NAMESPACE - -#endif // Hadrons____FILEBASENAME____hpp_ diff --git a/extras/Hadrons/Modules/templates/Module_tmp_in_NS.cc.template b/extras/Hadrons/Modules/templates/Module_tmp_in_NS.cc.template new file mode 100644 index 00000000..8dfafcf8 --- /dev/null +++ b/extras/Hadrons/Modules/templates/Module_tmp_in_NS.cc.template @@ -0,0 +1,7 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace ___NAMESPACE___; + +template class Grid::Hadrons::___NAMESPACE___::T___FILEBASENAME___; diff --git a/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template b/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template index 48df254b..5a05a498 100644 --- a/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template +++ b/extras/Hadrons/Modules/templates/Module_tmp_in_NS.hpp.template @@ -26,7 +26,7 @@ public: // constructor T___FILEBASENAME___(const std::string name); // destructor - virtual ~T___FILEBASENAME___(void) = default; + virtual ~T___FILEBASENAME___(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); diff --git a/extras/Hadrons/add_module.sh b/extras/Hadrons/add_module.sh index d5d23ea4..e37d19b1 100755 --- a/extras/Hadrons/add_module.sh +++ b/extras/Hadrons/add_module.sh @@ -1,31 +1,22 @@ #!/usr/bin/env bash -if (( $# != 1 && $# != 2)); then - echo "usage: `basename $0` []" 1>&2 +if (( $# != 2 )); then + echo "usage: `basename $0` " 1>&2 exit 1 fi NAME=$1 NS=$2 -if (( $# == 1 )); then - if [ -e "Modules/${NAME}.cc" ] || [ -e "Modules/${NAME}.hpp" ]; then - echo "error: files Modules/${NAME}.* already exists" 1>&2 - exit 1 - fi - sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module.cc.template > Modules/${NAME}.cc - sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module.hpp.template > Modules/${NAME}.hpp -elif (( $# == 2 )); then - mkdir -p Modules/${NS} - if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then - echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2 - exit 1 - fi - TMPCC=".${NS}.${NAME}.tmp.cc" - TMPHPP=".${NS}.${NAME}.tmp.hpp" - sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.cc.template > ${TMPCC} - sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.hpp.template > ${TMPHPP} - sed "s/___NAMESPACE___/${NS}/g" ${TMPCC} > Modules/${NS}/${NAME}.cc - sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp - rm -f ${TMPCC} ${TMPHPP} +mkdir -p Modules/${NS} +if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then + echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2 + exit 1 fi +TMPCC=".${NS}.${NAME}.tmp.cc" +TMPHPP=".${NS}.${NAME}.tmp.hpp" +sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.cc.template > ${TMPCC} +sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.hpp.template > ${TMPHPP} +sed "s/___NAMESPACE___/${NS}/g" ${TMPCC} > Modules/${NS}/${NAME}.cc +sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp +rm -f ${TMPCC} ${TMPHPP} ./make_module_list.sh diff --git a/extras/Hadrons/add_module_template.sh b/extras/Hadrons/add_module_template.sh index 0069fcea..8ba112dd 100755 --- a/extras/Hadrons/add_module_template.sh +++ b/extras/Hadrons/add_module_template.sh @@ -1,28 +1,22 @@ #!/usr/bin/env bash -if (( $# != 1 && $# != 2)); then - echo "usage: `basename $0` []" 1>&2 +if (( $# != 2)); then + echo "usage: `basename $0` " 1>&2 exit 1 fi NAME=$1 NS=$2 -if (( $# == 1 )); then - if [ -e "Modules/${NAME}.cc" ] || [ -e "Modules/${NAME}.hpp" ]; then - echo "error: files Modules/${NAME}.* already exists" 1>&2 - exit 1 - fi - sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp.hpp.template > Modules/${NAME}.hpp -elif (( $# == 2 )); then - mkdir -p Modules/${NS} - if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then - echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2 - exit 1 - fi - TMPCC=".${NS}.${NAME}.tmp.cc" - TMPHPP=".${NS}.${NAME}.tmp.hpp" - sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp_in_NS.hpp.template > ${TMPHPP} - sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp - rm -f ${TMPCC} ${TMPHPP} +mkdir -p Modules/${NS} +if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then + echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2 + exit 1 fi +TMPCC=".${NS}.${NAME}.tmp.cc" +TMPHPP=".${NS}.${NAME}.tmp.hpp" +sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp_in_NS.cc.template > ${TMPCC} +sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp_in_NS.hpp.template > ${TMPHPP} +sed "s/___NAMESPACE___/${NS}/g" ${TMPCC} > Modules/${NS}/${NAME}.cc +sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp +rm -f ${TMPCC} ${TMPHPP} ./make_module_list.sh From 75113e6523bf5a5687c27c826a8b8e892722a84a Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 19:49:27 +0100 Subject: [PATCH 063/126] Hadrons: Scalar SU(N) variable name update --- extras/Hadrons/Modules/MScalarSUN/Utils.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/Utils.hpp b/extras/Hadrons/Modules/MScalarSUN/Utils.hpp index 1a17282a..b9e49715 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Utils.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Utils.hpp @@ -89,15 +89,20 @@ inline void dmuAcc(Field &out, const Field &in, const unsigned int mu, const Dif } } +inline std::string varName(const std::string name, const std::string suf) +{ + return name + "_" + suf; +} + inline std::string varName(const std::string name, const unsigned int mu) { - return name + "_" + std::to_string(mu); + return varName(name, std::to_string(mu)); } inline std::string varName(const std::string name, const unsigned int mu, const unsigned int nu) { - return name + "_" + std::to_string(mu) + "_" + std::to_string(nu); + return varName(name, std::to_string(mu) + "_" + std::to_string(nu)); } END_MODULE_NAMESPACE From a13106da0cb40469cfecb281ee619186bf7f95fc Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 19:49:51 +0100 Subject: [PATCH 064/126] Hadrons: scalar SU(N) gradient --- extras/Hadrons/Modules.hpp | 1 + extras/Hadrons/Modules/MScalarSUN/Grad.cc | 38 +++++ extras/Hadrons/Modules/MScalarSUN/Grad.hpp | 165 +++++++++++++++++++++ extras/Hadrons/modules.inc | 2 + 4 files changed, 206 insertions(+) create mode 100644 extras/Hadrons/Modules/MScalarSUN/Grad.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/Grad.hpp diff --git a/extras/Hadrons/Modules.hpp b/extras/Hadrons/Modules.hpp index 528faecd..fc536393 100644 --- a/extras/Hadrons/Modules.hpp +++ b/extras/Hadrons/Modules.hpp @@ -69,6 +69,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include #include +#include #include #include #include diff --git a/extras/Hadrons/Modules/MScalarSUN/Grad.cc b/extras/Hadrons/Modules/MScalarSUN/Grad.cc new file mode 100644 index 00000000..be03b4a7 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/Grad.cc @@ -0,0 +1,38 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/Grad.cc + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +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 + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TGrad>; +template class Grid::Hadrons::MScalarSUN::TGrad>; +template class Grid::Hadrons::MScalarSUN::TGrad>; +template class Grid::Hadrons::MScalarSUN::TGrad>; +template class Grid::Hadrons::MScalarSUN::TGrad>; diff --git a/extras/Hadrons/Modules/MScalarSUN/Grad.hpp b/extras/Hadrons/Modules/MScalarSUN/Grad.hpp new file mode 100644 index 00000000..7718fbf2 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/Grad.hpp @@ -0,0 +1,165 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: extras/Hadrons/Modules/MScalarSUN/Grad.hpp + +Copyright (C) 2015-2018 + +Author: Antonin Portelli + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +See the full license in the file "LICENSE" in the top level distribution directory +*************************************************************************************/ +/* END LEGAL */ +#ifndef Hadrons_MScalarSUN_Grad_hpp_ +#define Hadrons_MScalarSUN_Grad_hpp_ + +#include +#include +#include +#include + +BEGIN_HADRONS_NAMESPACE + +/****************************************************************************** + * Gradient of a complex field * + ******************************************************************************/ +BEGIN_MODULE_NAMESPACE(MScalarSUN) + +class GradPar: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(GradPar, + std::string, op, + DiffType, type, + std::string, output); +}; + +template +class TGrad: public Module +{ +public: + typedef typename SImpl::Field Field; + typedef typename SImpl::ComplexField ComplexField; + class Result: Serializable + { + public: + GRID_SERIALIZABLE_CLASS_MEMBERS(Result, + DiffType, type, + Complex, value); + }; +public: + // constructor + TGrad(const std::string name); + // destructor + virtual ~TGrad(void) {}; + // dependency relation + virtual std::vector getInput(void); + virtual std::vector getOutput(void); + // setup + virtual void setup(void); + // execution + virtual void execute(void); +}; + +MODULE_REGISTER_TMP(GradSU2, TGrad>, MScalarSUN); +MODULE_REGISTER_TMP(GradSU3, TGrad>, MScalarSUN); +MODULE_REGISTER_TMP(GradSU4, TGrad>, MScalarSUN); +MODULE_REGISTER_TMP(GradSU5, TGrad>, MScalarSUN); +MODULE_REGISTER_TMP(GradSU6, TGrad>, MScalarSUN); + +/****************************************************************************** + * TGrad implementation * + ******************************************************************************/ +// constructor ///////////////////////////////////////////////////////////////// +template +TGrad::TGrad(const std::string name) +: Module(name) +{} + +// dependencies/products /////////////////////////////////////////////////////// +template +std::vector TGrad::getInput(void) +{ + std::vector in = {par().op}; + + return in; +} + +template +std::vector TGrad::getOutput(void) +{ + std::vector out; + const auto nd = env().getNd(); + + for (unsigned int mu = 0; mu < nd; ++mu) + { + out.push_back(varName(getName(), mu)); + } + + return out; +} + +// setup /////////////////////////////////////////////////////////////////////// +template +void TGrad::setup(void) +{ + const auto nd = env().getNd(); + + for (unsigned int mu = 0; mu < nd; ++mu) + { + envCreateLat(ComplexField, varName(getName(), mu)); + } +} + +// execution /////////////////////////////////////////////////////////////////// +template +void TGrad::execute(void) +{ + const auto nd = env().getNd(); + + LOG(Message) << "Computing the " << par().type << " gradient of '" + << par().op << "'" << std::endl; + + std::vector result; + auto &op = envGet(ComplexField, par().op); + + for (unsigned int mu = 0; mu < nd; ++mu) + { + auto &der = envGet(ComplexField, varName(getName(), mu)); + + dmu(der, op, mu, par().type); + if (!par().output.empty()) + { + Result r; + + r.type = par().type; + r.value = TensorRemove(sum(der)); + result.push_back(r); + } + } + if (result.size() > 0) + { + saveResult(par().output, "grad", result); + } +} + +END_MODULE_NAMESPACE + +END_HADRONS_NAMESPACE + +#endif // Hadrons_MScalarSUN_Grad_hpp_ diff --git a/extras/Hadrons/modules.inc b/extras/Hadrons/modules.inc index ec954bbe..ad3a8727 100644 --- a/extras/Hadrons/modules.inc +++ b/extras/Hadrons/modules.inc @@ -31,6 +31,7 @@ modules_cc =\ Modules/MAction/WilsonClover.cc \ Modules/MAction/DWF.cc \ Modules/MScalarSUN/TrPhi.cc \ + Modules/MScalarSUN/Grad.cc \ Modules/MScalarSUN/TrMag.cc \ Modules/MScalarSUN/TrKinetic.cc \ Modules/MScalarSUN/EMT.cc \ @@ -85,6 +86,7 @@ modules_hpp =\ Modules/MScalarSUN/TrPhi.hpp \ Modules/MScalarSUN/Utils.hpp \ Modules/MScalarSUN/TransProj.hpp \ + Modules/MScalarSUN/Grad.hpp \ Modules/MScalarSUN/TrKinetic.hpp \ Modules/MIO/LoadEigenPack.hpp \ Modules/MIO/LoadNersc.hpp \ From 047ee4ad0bbf75e9ab728947ad3b680bac416e0c Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 19:50:58 +0100 Subject: [PATCH 065/126] Hadrons: scalar SU(N) cleanup --- extras/Hadrons/Modules/MScalarSUN/Div.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.hpp b/extras/Hadrons/Modules/MScalarSUN/Div.hpp index 4382eb9f..d1f6df26 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Div.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Div.hpp @@ -126,7 +126,7 @@ void TDiv::execute(void) LOG(Message) << "Computing the " << par().type << " divergence of ["; for (unsigned int mu = 0; mu < nd; ++mu) { - std::cout << par().op[mu] << ((mu == nd - 1) ? "]" : ", "); + std::cout << "'" << par().op[mu] << ((mu == nd - 1) ? "']" : "', "); } std::cout << std::endl; From c1d0359aaa05518b9668452f73c08a3312af80d8 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 19:51:22 +0100 Subject: [PATCH 066/126] Hadrons: scalar SU(N) kinetic term saves trace --- extras/Hadrons/Modules/MScalarSUN/EMT.hpp | 11 ++------- .../Hadrons/Modules/MScalarSUN/TrKinetic.hpp | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp index fbc9c62a..025b7936 100644 --- a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp @@ -104,6 +104,7 @@ std::vector TEMT::getInput(void) in.push_back(varName(par().improvement, mu, nu)); } } + in.push_back(varName(par().kinetic, "sum")); in.push_back(varName(par().phiPow, 2)); in.push_back(varName(par().phiPow, 4)); @@ -133,7 +134,6 @@ void TEMT::setup(void) { envCreateLat(ComplexField, varName(getName(), mu, nu)); } - envTmpLat(ComplexField, "sumkin"); } // execution /////////////////////////////////////////////////////////////////// @@ -158,15 +158,8 @@ void TEMT::execute(void) const unsigned int N = SImpl::Group::Dimension; auto &trphi2 = envGet(ComplexField, varName(par().phiPow, 2)); auto &trphi4 = envGet(ComplexField, varName(par().phiPow, 4)); + auto &sumkin = envGet(ComplexField, varName(par().kinetic, "sum")); - envGetTmp(ComplexField, sumkin); - sumkin = zero; - for (unsigned int mu = 0; mu < env().getNd(); ++mu) - { - auto &trkin = envGet(ComplexField, varName(par().kinetic, mu, mu)); - - sumkin += trkin; - } for (unsigned int mu = 0; mu < env().getNd(); ++mu) for (unsigned int nu = mu; nu < env().getNd(); ++nu) { diff --git a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp index a8c7f521..59aa27b8 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp @@ -110,6 +110,7 @@ std::vector TTrKinetic::getOutput(void) { out.push_back(varName(getName(), mu, nu)); } + out.push_back(varName(getName(), "sum")); return out; } @@ -123,6 +124,7 @@ void TTrKinetic::setup(void) { envCreateLat(ComplexField, varName(getName(), mu, nu)); } + envCreateLat(ComplexField, varName(getName(), "sum")); envTmp(std::vector, "der", 1, env().getNd(), env().getGrid()); } @@ -134,9 +136,11 @@ void TTrKinetic::execute(void) << " derivative" << std::endl; std::vector result; - auto &phi = envGet(Field, par().field); + auto &phi = envGet(Field, par().field); + auto &sumkin = envGet(ComplexField, varName(getName(), "sum")); envGetTmp(std::vector, der); + sumkin = zero; for (unsigned int mu = 0; mu < env().getNd(); ++mu) { dmu(der[mu], phi, mu, par().type); @@ -147,8 +151,17 @@ void TTrKinetic::execute(void) auto &out = envGet(ComplexField, varName(getName(), mu, nu)); out = -trace(der[mu]*der[nu]); - if (!par().output.empty()) + if (mu == nu) { + sumkin += out; + } + } + if (!par().output.empty()) + { + for (unsigned int mu = 0; mu < env().getNd(); ++mu) + for (unsigned int nu = mu; nu < env().getNd(); ++nu) + { + auto &out = envGet(ComplexField, varName(getName(), mu, nu)); Result r; r.op = "tr(d_" + std::to_string(mu) + "phi*d_" @@ -156,6 +169,13 @@ void TTrKinetic::execute(void) r.value = TensorRemove(sum(out)); result.push_back(r); } + { + Result r; + + r.op = "sum_mu tr(d_mu phi*d_mu phi)"; + r.value = TensorRemove(sum(sumkin)); + result.push_back(r); + } } if (result.size() > 0) { From 6ea2a8b7caa33456c0c50b21c9e1e63ac9fd6920 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 19:51:47 +0100 Subject: [PATCH 067/126] Hadrons: scheduler shows starting value --- extras/Hadrons/GeneticScheduler.hpp | 4 ++-- extras/Hadrons/VirtualMachine.cc | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/extras/Hadrons/GeneticScheduler.hpp b/extras/Hadrons/GeneticScheduler.hpp index e8fcd2c2..83666402 100644 --- a/extras/Hadrons/GeneticScheduler.hpp +++ b/extras/Hadrons/GeneticScheduler.hpp @@ -58,6 +58,8 @@ public: // access const Gene & getMinSchedule(void); V getMinValue(void); + // reset population + void initPopulation(void); // breed a new generation void nextGeneration(void); // heuristic benchmarks @@ -76,8 +78,6 @@ public: return out; } private: - // evolution steps - void initPopulation(void); void doCrossover(void); void doMutation(void); // genetic operators diff --git a/extras/Hadrons/VirtualMachine.cc b/extras/Hadrons/VirtualMachine.cc index 49096d92..dffabe29 100644 --- a/extras/Hadrons/VirtualMachine.cc +++ b/extras/Hadrons/VirtualMachine.cc @@ -596,6 +596,9 @@ VirtualMachine::Program VirtualMachine::schedule(const GeneticPar &par) }; Scheduler scheduler(graph, memPeak, gpar); gen = 0; + scheduler.initPopulation(); + LOG(Iterative) << "Start: " << sizeString(scheduler.getMinValue()) + << std::endl; do { //LOG(Debug) << "Generation " << gen << ":" << std::endl; From b234784c8edf156916d54d7eeebc7bea07373d1b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 24 Apr 2018 19:52:12 +0100 Subject: [PATCH 068/126] Hadrons: scalar SU(N) takes operator pairs now --- .../Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index 27edf370..c31b1621 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -43,8 +43,9 @@ BEGIN_MODULE_NAMESPACE(MScalarSUN) class TwoPointPar: Serializable { public: + typedef std::pair OpPair; GRID_SERIALIZABLE_CLASS_MEMBERS(TwoPointPar, - std::vector, op, + std::vector, op, std::vector, mom, std::string, output); }; @@ -106,7 +107,20 @@ TTwoPoint::TTwoPoint(const std::string name) template std::vector TTwoPoint::getInput(void) { - return par().op; + std::vector in; + std::set ops; + + for (auto &p: par().op) + { + ops.insert(p.first); + ops.insert(p.second); + } + for (auto &o: ops) + { + in.push_back(o); + } + + return in; } template @@ -140,54 +154,59 @@ void TTwoPoint::setup(void) template void TTwoPoint::execute(void) { - LOG(Message) << "Computing 2-point functions for operators:" << std::endl; - for (auto &o: par().op) + LOG(Message) << "Computing 2-point functions" << std::endl; + for (auto &p: par().op) { - LOG(Message) << " '" << o << "'" << std::endl; + LOG(Message) << " <" << p.first << " " << p.second << ">" << std::endl; } - const unsigned int nd = env().getDim().size(); - const unsigned int nt = env().getDim().back(); - const unsigned int nop = par().op.size(); - const unsigned int nmom = mom_.size(); - std::vector dMask(nd, 1); - std::vector result; - std::vector> slicedOp(nop); - FFT fft(env().getGrid()); + const unsigned int nd = env().getDim().size(); + const unsigned int nt = env().getDim().back(); + const unsigned int nop = par().op.size(); + const unsigned int nmom = mom_.size(); + std::vector dMask(nd, 1); + std::set ops; + std::vector result; + std::map> slicedOp; + FFT fft(env().getGrid()); envGetTmp(ComplexField, ftBuf); dMask[nd - 1] = 0; - for (unsigned int i = 0; i < nop; ++i) + for (auto &p: par().op) { - auto &op = envGet(ComplexField, par().op[i]); + ops.insert(p.first); + ops.insert(p.second); + } + for (auto &o: ops) + { + auto &op = envGet(ComplexField, o); - slicedOp[i].resize(nmom); - LOG(Message) << "Operator '" << par().op[i] << "' FFT" << std::endl; - fft.FFT_dim_mask(ftBuf, op, dMask, FFT::forward); + slicedOp[o].resize(nmom); + LOG(Message) << "Operator '" << o << "' FFT" << std::endl; + fft.FFT_dim_mask(ftBuf, op, dMask, FFT::backward); for (unsigned int m = 0; m < nmom; ++m) { auto qt = mom_[m]; qt.resize(nd); - slicedOp[i][m].resize(nt); + slicedOp[o][m].resize(nt); for (unsigned int t = 0; t < nt; ++t) { qt[nd - 1] = t; - peekSite(slicedOp[i][m][t], ftBuf, qt); + peekSite(slicedOp[o][m][t], ftBuf, qt); } } } LOG(Message) << "Making contractions" << std::endl; for (unsigned int m = 0; m < nmom; ++m) - for (unsigned int i = 0; i < nop; ++i) - for (unsigned int j = 0; j < nop; ++j) + for (auto &p: par().op) { Result r; - r.sink = par().op[i]; - r.source = par().op[j]; + r.sink = p.first; + r.source = p.second; r.mom = mom_[m]; - r.data = makeTwoPoint(slicedOp[i][m], slicedOp[j][m]); + r.data = makeTwoPoint(slicedOp[p.first][m], slicedOp[p.second][m]); result.push_back(r); } saveResult(par().output, "twopt", result); From 276a2353dfca4677c687effc524b36b5ccfb054b Mon Sep 17 00:00:00 2001 From: paboyle Date: Wed, 25 Apr 2018 00:11:07 +0100 Subject: [PATCH 069/126] Move constructor --- lib/lattice/Lattice_base.h | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/lattice/Lattice_base.h b/lib/lattice/Lattice_base.h index 014e443d..dcd55702 100644 --- a/lib/lattice/Lattice_base.h +++ b/lib/lattice/Lattice_base.h @@ -257,7 +257,11 @@ public: } } - + Lattice(Lattice&& r){ // move constructor + _grid = r._grid; + checkerboard = r.checkerboard; + _odata=std::move(r._odata); + } virtual ~Lattice(void) = default; @@ -286,6 +290,24 @@ public: } return *this; } + + strong_inline Lattice & operator = (const Lattice & r){ + _grid = r._grid; + checkerboard = r.checkerboard; + _odata.resize(_grid->oSites());// essential + + parallel_for(int ss=0;ss<_grid->oSites();ss++){ + _odata[ss]=r._odata[ss]; + } + return *this; + } + strong_inline Lattice & operator = (Lattice && r) + { + _grid = r._grid; + checkerboard = r.checkerboard; + _odata =std::move(r._odata); + return *this; + } // *=,+=,-= operators inherit behvour from correspond */+/- operation template strong_inline Lattice &operator *=(const T &r) { From 362ba0443ad73dc726fd45bcf0f7b3447ec9fb11 Mon Sep 17 00:00:00 2001 From: paboyle Date: Wed, 25 Apr 2018 00:12:11 +0100 Subject: [PATCH 070/126] Cshift updates --- benchmarks/Benchmark_su3.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index 628ad5bd..b458d48a 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -35,17 +35,18 @@ using namespace Grid::QCD; int main (int argc, char ** argv) { Grid_init(&argc,&argv); -#define LMAX (40) +#define LMAX (16) +#define LMIN (16) #define LINC (4) - int64_t Nloop=20; + int64_t Nloop=2000; std::vector simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd()); std::vector mpi_layout = GridDefaultMpi(); int64_t threads = GridThread::GetThreads(); std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -190,7 +191,7 @@ int main (int argc, char ** argv) LatticeColourMatrix x(&Grid); random(pRNG,x); LatticeColourMatrix y(&Grid); random(pRNG,y); - for(int mu=0;mu<=4;mu++){ + for(int mu=0;mu<4;mu++){ double start=usecond(); for(int64_t i=0;i Date: Wed, 25 Apr 2018 16:49:14 +0100 Subject: [PATCH 071/126] Hadrons: macro refactoring for library portability --- extras/Hadrons/Application.cc | 8 ++++---- extras/Hadrons/EigenPack.hpp | 2 +- extras/Hadrons/Environment.cc | 16 ++++++++-------- extras/Hadrons/Environment.hpp | 12 ++++++------ extras/Hadrons/Exceptions.hpp | 8 ++++---- extras/Hadrons/Factory.hpp | 2 +- extras/Hadrons/Global.hpp | 2 +- extras/Hadrons/Graph.hpp | 12 ++++++------ extras/Hadrons/Module.cc | 2 +- extras/Hadrons/Module.hpp | 2 +- .../Modules/MContraction/WardIdentity.hpp | 2 +- extras/Hadrons/Modules/MFermion/GaugeProp.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/Div.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp | 4 ++-- extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 2 +- extras/Hadrons/Modules/MScalarSUN/Utils.hpp | 8 ++++---- extras/Hadrons/Modules/MSolver/RBPrecCG.hpp | 2 +- .../Modules/MUtilities/TestSeqConserved.hpp | 2 +- extras/Hadrons/VirtualMachine.cc | 14 +++++++------- extras/Hadrons/VirtualMachine.hpp | 2 +- lib/qcd/modules/Factory.h | 2 +- 22 files changed, 55 insertions(+), 55 deletions(-) diff --git a/extras/Hadrons/Application.cc b/extras/Hadrons/Application.cc index 4c7e71f2..f409d8eb 100644 --- a/extras/Hadrons/Application.cc +++ b/extras/Hadrons/Application.cc @@ -114,12 +114,12 @@ void Application::parseParameterFile(const std::string parameterFileName) setPar(par); if (!push(reader, "modules")) { - HADRON_ERROR(Parsing, "Cannot open node 'modules' in parameter file '" + HADRONS_ERROR(Parsing, "Cannot open node 'modules' in parameter file '" + parameterFileName + "'"); } if (!push(reader, "module")) { - HADRON_ERROR(Parsing, "Cannot open node 'modules/module' in parameter file '" + HADRONS_ERROR(Parsing, "Cannot open node 'modules/module' in parameter file '" + parameterFileName + "'"); } do @@ -177,7 +177,7 @@ void Application::saveSchedule(const std::string filename) if (!scheduled_) { - HADRON_ERROR(Definition, "Computation not scheduled"); + HADRONS_ERROR(Definition, "Computation not scheduled"); } for (auto address: program_) @@ -208,7 +208,7 @@ void Application::printSchedule(void) { if (!scheduled_) { - HADRON_ERROR(Definition, "Computation not scheduled"); + HADRONS_ERROR(Definition, "Computation not scheduled"); } auto peak = vm().memoryNeeded(program_); LOG(Message) << "Schedule (memory needed: " << sizeString(peak) << "):" diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 5f403595..976fba7b 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -123,7 +123,7 @@ protected: binReader.readScidacFieldRecord(evec[k], vecRecord); if (vecRecord.index != k) { - HADRON_ERROR(Io, "Eigenvector " + std::to_string(k) + " has a" + HADRONS_ERROR(Io, "Eigenvector " + std::to_string(k) + " has a" + " wrong index (expected " + std::to_string(vecRecord.index) + ") in file '" + filename + "'"); } diff --git a/extras/Hadrons/Environment.cc b/extras/Hadrons/Environment.cc index 35bb4648..990a717e 100644 --- a/extras/Hadrons/Environment.cc +++ b/extras/Hadrons/Environment.cc @@ -35,7 +35,7 @@ using namespace QCD; using namespace Hadrons; #define ERROR_NO_ADDRESS(address)\ -HADRON_ERROR(Definition, "no object with address " + std::to_string(address)); +HADRONS_ERROR(Definition, "no object with address " + std::to_string(address)); /****************************************************************************** * Environment implementation * @@ -85,7 +85,7 @@ void Environment::createCoarseGrid(const std::vector &blockSize, coarseDim[d] = fineDim[d]/blockSize[d]; if (coarseDim[d]*blockSize[d] != fineDim[d]) { - HADRON_ERROR(Size, "Fine dimension " + std::to_string(d) + HADRONS_ERROR(Size, "Fine dimension " + std::to_string(d) + " (" + std::to_string(fineDim[d]) + ") not divisible by coarse dimension (" + std::to_string(coarseDim[d]) + ")"); @@ -96,7 +96,7 @@ void Environment::createCoarseGrid(const std::vector &blockSize, cLs = Ls/blockSize[nd]; if (cLs*blockSize[nd] != Ls) { - HADRON_ERROR(Size, "Fine Ls (" + std::to_string(Ls) + HADRONS_ERROR(Size, "Fine Ls (" + std::to_string(Ls) + ") not divisible by coarse Ls (" + std::to_string(cLs) + ")"); } @@ -128,7 +128,7 @@ GridCartesian * Environment::getGrid(const unsigned int Ls) const } catch(std::out_of_range &) { - HADRON_ERROR(Definition, "no grid with Ls= " + std::to_string(Ls)); + HADRONS_ERROR(Definition, "no grid with Ls= " + std::to_string(Ls)); } } @@ -147,7 +147,7 @@ GridRedBlackCartesian * Environment::getRbGrid(const unsigned int Ls) const } catch(std::out_of_range &) { - HADRON_ERROR(Definition, "no red-black grid with Ls= " + std::to_string(Ls)); + HADRONS_ERROR(Definition, "no red-black grid with Ls= " + std::to_string(Ls)); } } @@ -171,7 +171,7 @@ GridCartesian * Environment::getCoarseGrid( } catch(std::out_of_range &) { - HADRON_ERROR(Definition, "no coarse grid with Ls= " + std::to_string(Ls)); + HADRONS_ERROR(Definition, "no coarse grid with Ls= " + std::to_string(Ls)); } } @@ -221,7 +221,7 @@ void Environment::addObject(const std::string name, const int moduleAddress) } else { - HADRON_ERROR(Definition, "object '" + name + "' already exists"); + HADRONS_ERROR(Definition, "object '" + name + "' already exists"); } } @@ -244,7 +244,7 @@ unsigned int Environment::getObjectAddress(const std::string name) const } else { - HADRON_ERROR(Definition, "no object with name '" + name + "'"); + HADRONS_ERROR(Definition, "no object with name '" + name + "'"); } } diff --git a/extras/Hadrons/Environment.hpp b/extras/Hadrons/Environment.hpp index f624f36e..a9c3c724 100644 --- a/extras/Hadrons/Environment.hpp +++ b/extras/Hadrons/Environment.hpp @@ -245,7 +245,7 @@ void Environment::createDerivedObject(const std::string name, (object_[address].type != &typeid(B)) or (object_[address].derivedType != &typeid(T))) { - HADRON_ERROR(Definition, "object '" + name + "' already allocated"); + HADRONS_ERROR(Definition, "object '" + name + "' already allocated"); } } @@ -279,7 +279,7 @@ T * Environment::getDerivedObject(const unsigned int address) const } else { - HADRON_ERROR(Definition, "object with address " + std::to_string(address) + + HADRONS_ERROR(Definition, "object with address " + std::to_string(address) + " cannot be casted to '" + typeName(&typeid(T)) + "' (has type '" + typeName(&typeid(h->get())) + "')"); } @@ -287,20 +287,20 @@ T * Environment::getDerivedObject(const unsigned int address) const } else { - HADRON_ERROR(Definition, "object with address " + std::to_string(address) + + HADRONS_ERROR(Definition, "object with address " + std::to_string(address) + " does not have type '" + typeName(&typeid(B)) + "' (has type '" + getObjectType(address) + "')"); } } else { - HADRON_ERROR(Definition, "object with address " + std::to_string(address) + + HADRONS_ERROR(Definition, "object with address " + std::to_string(address) + " is empty"); } } else { - HADRON_ERROR(Definition, "no object with address " + std::to_string(address)); + HADRONS_ERROR(Definition, "no object with address " + std::to_string(address)); } } @@ -338,7 +338,7 @@ bool Environment::isObjectOfType(const unsigned int address) const } else { - HADRON_ERROR(Definition, "no object with address " + std::to_string(address)); + HADRONS_ERROR(Definition, "no object with address " + std::to_string(address)); } } diff --git a/extras/Hadrons/Exceptions.hpp b/extras/Hadrons/Exceptions.hpp index adf2340f..3eb1c25f 100644 --- a/extras/Hadrons/Exceptions.hpp +++ b/extras/Hadrons/Exceptions.hpp @@ -34,10 +34,10 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #endif -#define SRC_LOC std::string(__FUNCTION__) + " at " + std::string(__FILE__) + ":"\ - + std::to_string(__LINE__) -#define HADRON_ERROR(exc, msg)\ -throw(Exceptions::exc(msg, SRC_LOC)); +#define HADRONS_SRC_LOC std::string(__FUNCTION__) + " at " \ + + std::string(__FILE__) + ":" + std::to_string(__LINE__) +#define HADRONS_ERROR(exc, msg)\ +throw(Exceptions::exc(msg, HADRONS_SRC_LOC)); #define DECL_EXC(name, base) \ class name: public base\ diff --git a/extras/Hadrons/Factory.hpp b/extras/Hadrons/Factory.hpp index 705a639e..07516640 100644 --- a/extras/Hadrons/Factory.hpp +++ b/extras/Hadrons/Factory.hpp @@ -94,7 +94,7 @@ std::unique_ptr Factory::create(const std::string type, } catch (std::out_of_range &) { - HADRON_ERROR(Argument, "object of type '" + type + "' unknown"); + HADRONS_ERROR(Argument, "object of type '" + type + "' unknown"); } return func(name); diff --git a/extras/Hadrons/Global.hpp b/extras/Hadrons/Global.hpp index 5e729579..433dcd21 100644 --- a/extras/Hadrons/Global.hpp +++ b/extras/Hadrons/Global.hpp @@ -110,7 +110,7 @@ public: }; #define LOG(channel) std::cout << HadronsLog##channel -#define DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl; +#define HADRONS_DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl; extern HadronsLogger HadronsLogError; extern HadronsLogger HadronsLogWarning; diff --git a/extras/Hadrons/Graph.hpp b/extras/Hadrons/Graph.hpp index 67694aa8..ad84e7e0 100644 --- a/extras/Hadrons/Graph.hpp +++ b/extras/Hadrons/Graph.hpp @@ -184,7 +184,7 @@ void Graph::removeVertex(const T &value) } else { - HADRON_ERROR(Range, "vertex does not exists"); + HADRONS_ERROR(Range, "vertex does not exists"); } // remove all edges containing the vertex @@ -213,7 +213,7 @@ void Graph::removeEdge(const Edge &e) } else { - HADRON_ERROR(Range, "edge does not exists"); + HADRONS_ERROR(Range, "edge does not exists"); } } @@ -259,7 +259,7 @@ void Graph::mark(const T &value, const bool doMark) } else { - HADRON_ERROR(Range, "vertex does not exists"); + HADRONS_ERROR(Range, "vertex does not exists"); } } @@ -297,7 +297,7 @@ bool Graph::isMarked(const T &value) const } else { - HADRON_ERROR(Range, "vertex does not exists"); + HADRONS_ERROR(Range, "vertex does not exists"); return false; } @@ -543,7 +543,7 @@ std::vector Graph::topoSort(void) { if (tmpMarked.at(v)) { - HADRON_ERROR(Range, "cannot topologically sort a cyclic graph"); + HADRONS_ERROR(Range, "cannot topologically sort a cyclic graph"); } if (!isMarked(v)) { @@ -602,7 +602,7 @@ std::vector Graph::topoSort(Gen &gen) { if (tmpMarked.at(v)) { - HADRON_ERROR(Range, "cannot topologically sort a cyclic graph"); + HADRONS_ERROR(Range, "cannot topologically sort a cyclic graph"); } if (!isMarked(v)) { diff --git a/extras/Hadrons/Module.cc b/extras/Hadrons/Module.cc index 54978f93..faf01d5a 100644 --- a/extras/Hadrons/Module.cc +++ b/extras/Hadrons/Module.cc @@ -49,7 +49,7 @@ std::string ModuleBase::getName(void) const // get factory registration name if available std::string ModuleBase::getRegisteredName(void) { - HADRON_ERROR(Definition, "module '" + getName() + "' has no registered type" + HADRONS_ERROR(Definition, "module '" + getName() + "' has no registered type" + " in the factory"); } diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 656aacef..7f8b7796 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -126,7 +126,7 @@ if (env().getGrid()->IsBoss())\ \ if (mkdir(_dirname))\ {\ - HADRON_ERROR(Io, "cannot create directory '" + _dirname + "'");\ + HADRONS_ERROR(Io, "cannot create directory '" + _dirname + "'");\ }\ {\ ResultWriter _writer(RESULT_FILE_NAME(ioStem));\ diff --git a/extras/Hadrons/Modules/MContraction/WardIdentity.hpp b/extras/Hadrons/Modules/MContraction/WardIdentity.hpp index f1ca6c2b..e529d7a2 100644 --- a/extras/Hadrons/Modules/MContraction/WardIdentity.hpp +++ b/extras/Hadrons/Modules/MContraction/WardIdentity.hpp @@ -119,7 +119,7 @@ void TWardIdentity::setup(void) Ls_ = env().getObjectLs(par().q); if (Ls_ != env().getObjectLs(par().action)) { - HADRON_ERROR(Size, "Ls mismatch between quark action and propagator"); + HADRONS_ERROR(Size, "Ls mismatch between quark action and propagator"); } envTmpLat(PropagatorField, "tmp"); envTmpLat(PropagatorField, "vector_WI"); diff --git a/extras/Hadrons/Modules/MFermion/GaugeProp.hpp b/extras/Hadrons/Modules/MFermion/GaugeProp.hpp index 9a359427..ee21cba9 100644 --- a/extras/Hadrons/Modules/MFermion/GaugeProp.hpp +++ b/extras/Hadrons/Modules/MFermion/GaugeProp.hpp @@ -177,7 +177,7 @@ void TGaugeProp::execute(void) { if (Ls_ != env().getObjectLs(par().source)) { - HADRON_ERROR(Size, "Ls mismatch between quark action and source"); + HADRONS_ERROR(Size, "Ls mismatch between quark action and source"); } else { diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.hpp b/extras/Hadrons/Modules/MScalarSUN/Div.hpp index d1f6df26..1b59fbed 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Div.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Div.hpp @@ -112,7 +112,7 @@ void TDiv::setup(void) { if (par().op.size() != env().getNd()) { - HADRON_ERROR(Size, "the number of components differs from number of dimensions"); + HADRONS_ERROR(Size, "the number of components differs from number of dimensions"); } envCreateLat(ComplexField, getName()); } diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp index 979a340e..c7c0e9ee 100644 --- a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp @@ -134,14 +134,14 @@ void TShiftProbe::execute(void) shift = strToVec(par().shifts); if (shift.size() % 2 != 0) { - HADRON_ERROR(Size, "the number of shifts is odd"); + HADRONS_ERROR(Size, "the number of shifts is odd"); } sign = (shift.size() % 4 == 0) ? 1 : -1; for (auto &s: shift) { if (s.first >= env().getNd()) { - HADRON_ERROR(Size, "dimension to large for shift <" + HADRONS_ERROR(Size, "dimension to large for shift <" + std::to_string(s.first) + " " + std::to_string(s.second) + ">" ); } diff --git a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp index a61c00bc..6c1d733b 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp @@ -119,7 +119,7 @@ void TTrPhi::setup(void) { if (par().maxPow < 2) { - HADRON_ERROR(Size, "'maxPow' should be at least equal to 2"); + HADRONS_ERROR(Size, "'maxPow' should be at least equal to 2"); } envTmpLat(Field, "phi2"); envTmpLat(Field, "buf"); diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index c31b1621..9e53553f 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -143,7 +143,7 @@ void TTwoPoint::setup(void) mom_[i] = strToVec(par().mom[i]); if (mom_[i].size() != nd - 1) { - HADRON_ERROR(Size, "momentum number of components different from " + HADRONS_ERROR(Size, "momentum number of components different from " + std::to_string(nd-1)); } } diff --git a/extras/Hadrons/Modules/MScalarSUN/Utils.hpp b/extras/Hadrons/Modules/MScalarSUN/Utils.hpp index b9e49715..37a9e137 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Utils.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Utils.hpp @@ -44,7 +44,7 @@ inline void dmu(Field &out, const Field &in, const unsigned int mu, const DiffTy if (mu >= env.getNd()) { - HADRON_ERROR(Range, "Derivative direction out of range"); + HADRONS_ERROR(Range, "Derivative direction out of range"); } switch(type) { @@ -58,7 +58,7 @@ inline void dmu(Field &out, const Field &in, const unsigned int mu, const DiffTy out = 0.5*(Cshift(in, mu, 1) - Cshift(in, mu, -1)); break; default: - HADRON_ERROR(Argument, "Derivative type invalid"); + HADRONS_ERROR(Argument, "Derivative type invalid"); break; } } @@ -70,7 +70,7 @@ inline void dmuAcc(Field &out, const Field &in, const unsigned int mu, const Dif if (mu >= env.getNd()) { - HADRON_ERROR(Range, "Derivative direction out of range"); + HADRONS_ERROR(Range, "Derivative direction out of range"); } switch(type) { @@ -84,7 +84,7 @@ inline void dmuAcc(Field &out, const Field &in, const unsigned int mu, const Dif out += 0.5*(Cshift(in, mu, 1) - Cshift(in, mu, -1)); break; default: - HADRON_ERROR(Argument, "Derivative type invalid"); + HADRONS_ERROR(Argument, "Derivative type invalid"); break; } } diff --git a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp index f559c4eb..206d44d1 100644 --- a/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp +++ b/extras/Hadrons/Modules/MSolver/RBPrecCG.hpp @@ -127,7 +127,7 @@ void TRBPrecCG::setup(void) { if (par().maxIteration == 0) { - HADRON_ERROR(Argument, "zero maximum iteration"); + HADRONS_ERROR(Argument, "zero maximum iteration"); } LOG(Message) << "setting up Schur red-black preconditioned CG for" diff --git a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp index dcd1ba9a..7b1bc1db 100644 --- a/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp +++ b/extras/Hadrons/Modules/MUtilities/TestSeqConserved.hpp @@ -123,7 +123,7 @@ void TTestSeqConserved::setup(void) auto Ls = env().getObjectLs(par().q); if (Ls != env().getObjectLs(par().action)) { - HADRON_ERROR(Size, "Ls mismatch between quark action and propagator"); + HADRONS_ERROR(Size, "Ls mismatch between quark action and propagator"); } envTmpLat(PropagatorField, "tmp"); envTmpLat(LatticeComplex, "c"); diff --git a/extras/Hadrons/VirtualMachine.cc b/extras/Hadrons/VirtualMachine.cc index dffabe29..cc197ef8 100644 --- a/extras/Hadrons/VirtualMachine.cc +++ b/extras/Hadrons/VirtualMachine.cc @@ -123,7 +123,7 @@ void VirtualMachine::pushModule(VirtualMachine::ModPt &pt) else { // output already fully registered, error - HADRON_ERROR(Definition, "object '" + out + HADRONS_ERROR(Definition, "object '" + out + "' is already produced by module '" + module_[env().getObjectModule(out)].name + "' (while pushing module '" + name + "')"); @@ -158,7 +158,7 @@ void VirtualMachine::pushModule(VirtualMachine::ModPt &pt) } else { - HADRON_ERROR(Definition, "module '" + name + "' already exists"); + HADRONS_ERROR(Definition, "module '" + name + "' already exists"); } } @@ -185,7 +185,7 @@ ModuleBase * VirtualMachine::getModule(const unsigned int address) const } else { - HADRON_ERROR(Definition, "no module with address " + std::to_string(address)); + HADRONS_ERROR(Definition, "no module with address " + std::to_string(address)); } } @@ -202,7 +202,7 @@ unsigned int VirtualMachine::getModuleAddress(const std::string name) const } else { - HADRON_ERROR(Definition, "no module with name '" + name + "'"); + HADRONS_ERROR(Definition, "no module with name '" + name + "'"); } } @@ -214,7 +214,7 @@ std::string VirtualMachine::getModuleName(const unsigned int address) const } else { - HADRON_ERROR(Definition, "no module with address " + std::to_string(address)); + HADRONS_ERROR(Definition, "no module with address " + std::to_string(address)); } } @@ -226,7 +226,7 @@ std::string VirtualMachine::getModuleType(const unsigned int address) const } else { - HADRON_ERROR(Definition, "no module with address " + std::to_string(address)); + HADRONS_ERROR(Definition, "no module with address " + std::to_string(address)); } } @@ -306,7 +306,7 @@ void VirtualMachine::makeModuleGraph(void) if (min < 0) { - HADRON_ERROR(Definition, "dependency '" + HADRONS_ERROR(Definition, "dependency '" + env().getObjectName(in) + "' (address " + std::to_string(in) + ") is not produced by any module"); diff --git a/extras/Hadrons/VirtualMachine.hpp b/extras/Hadrons/VirtualMachine.hpp index 153f8d70..ccc06d63 100644 --- a/extras/Hadrons/VirtualMachine.hpp +++ b/extras/Hadrons/VirtualMachine.hpp @@ -195,7 +195,7 @@ M * VirtualMachine::getModule(const unsigned int address) const } else { - HADRON_ERROR(Definition, "module '" + module_[address].name + HADRONS_ERROR(Definition, "module '" + module_[address].name + "' does not have type " + typeid(M).name() + "(has type: " + getModuleType(address) + ")"); } diff --git a/lib/qcd/modules/Factory.h b/lib/qcd/modules/Factory.h index 66bd627e..fafa2038 100644 --- a/lib/qcd/modules/Factory.h +++ b/lib/qcd/modules/Factory.h @@ -95,7 +95,7 @@ std::unique_ptr Factory::create(const std::string type, } catch (std::out_of_range &) { - //HADRON_ERROR("object of type '" + type + "' unknown"); + //HADRONS_ERROR("object of type '" + type + "' unknown"); std::cout << GridLogError << "Error" << std::endl; std::cout << GridLogError << obj_type() << " object of name [" << type << "] unknown" << std::endl; exit(1); From 43f5a0df50090b2f784653a3d3b2e569ae08b1a4 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 26 Apr 2018 12:01:56 +0900 Subject: [PATCH 072/126] More timers in the integrator --- benchmarks/Benchmark_su3.cc | 22 ++--- lib/qcd/hmc/integrators/Integrator.h | 12 ++- lib/qcd/smearing/GaugeConfiguration.h | 137 ++++++++++++++++---------- 3 files changed, 104 insertions(+), 67 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index d9f1341c..5f2d83d2 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -35,8 +35,8 @@ using namespace Grid::QCD; int main (int argc, char ** argv) { Grid_init(&argc,&argv); -#define LMAX (16) -#define LMIN (16) +#define LMAX (32) +#define LMIN (4) #define LINC (4) int64_t Nloop=2000; @@ -193,17 +193,17 @@ int main (int argc, char ** argv) LatticeColourMatrix y(&Grid); random(pRNG,y); for(int mu=0;mu<4;mu++){ - double start=usecond(); - for(int64_t i=0;iis_smeared); + double start_force = usecond(); as[level].actions.at(a)->deriv(Us, force); // deriv should NOT include Ta std::cout << GridLogIntegrator << "Smearing (on/off): " << as[level].actions.at(a)->is_smeared << std::endl; if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force); force = FieldImplementation::projectForce(force); // Ta for gauge fields + double end_force = usecond(); Real force_abs = std::sqrt(norm2(force)/U._grid->gSites()); - std::cout << GridLogIntegrator << "Force average: " << force_abs << std::endl; + std::cout << GridLogIntegrator << "["< -class NoSmearing { +//trivial class for no smearing +template +class NoSmearing +{ public: INHERIT_FIELD_TYPES(Impl); - Field* ThinField; + Field *ThinField; - NoSmearing(): ThinField(NULL) {} + NoSmearing() : ThinField(NULL) {} - void set_Field(Field& U) { ThinField = &U; } + void set_Field(Field &U) { ThinField = &U; } - void smeared_force(Field&) const {} + void smeared_force(Field &) const {} - Field& get_SmearedU() { return *ThinField; } + Field &get_SmearedU() { return *ThinField; } - Field& get_U(bool smeared = false) { + Field &get_U(bool smeared = false) + { return *ThinField; } - }; /*! @@ -44,32 +47,36 @@ public: It stores a list of smeared configurations. */ template -class SmearedConfiguration { - public: +class SmearedConfiguration +{ +public: INHERIT_GIMPL_TYPES(Gimpl); - private: +private: const unsigned int smearingLevels; Smear_Stout StoutSmearing; std::vector SmearedSet; // Member functions //==================================================================== - void fill_smearedSet(GaugeField& U) { - ThinLinks = &U; // attach the smearing routine to the field U + void fill_smearedSet(GaugeField &U) + { + ThinLinks = &U; // attach the smearing routine to the field U // check the pointer is not null if (ThinLinks == NULL) std::cout << GridLogError << "[SmearedConfiguration] Error in ThinLinks pointer\n"; - if (smearingLevels > 0) { + if (smearingLevels > 0) + { std::cout << GridLogDebug << "[SmearedConfiguration] Filling SmearedSet\n"; GaugeField previous_u(ThinLinks->_grid); previous_u = *ThinLinks; - for (int smearLvl = 0; smearLvl < smearingLevels; ++smearLvl) { + for (int smearLvl = 0; smearLvl < smearingLevels; ++smearLvl) + { StoutSmearing.smear(SmearedSet[smearLvl], previous_u); previous_u = SmearedSet[smearLvl]; @@ -81,9 +88,10 @@ class SmearedConfiguration { } } //==================================================================== - GaugeField AnalyticSmearedForce(const GaugeField& SigmaKPrime, - const GaugeField& GaugeK) const { - GridBase* grid = GaugeK._grid; + GaugeField AnalyticSmearedForce(const GaugeField &SigmaKPrime, + const GaugeField &GaugeK) const + { + GridBase *grid = GaugeK._grid; GaugeField C(grid), SigmaK(grid), iLambda(grid); GaugeLinkField iLambda_mu(grid); GaugeLinkField iQ(grid), e_iQ(grid); @@ -94,7 +102,8 @@ class SmearedConfiguration { SigmaK = zero; iLambda = zero; - for (int mu = 0; mu < Nd; mu++) { + for (int mu = 0; mu < Nd; mu++) + { Cmu = peekLorentz(C, mu); GaugeKmu = peekLorentz(GaugeK, mu); SigmaKPrime_mu = peekLorentz(SigmaKPrime, mu); @@ -104,20 +113,22 @@ class SmearedConfiguration { pokeLorentz(iLambda, iLambda_mu, mu); } StoutSmearing.derivative(SigmaK, iLambda, - GaugeK); // derivative of SmearBase + GaugeK); // derivative of SmearBase return SigmaK; } /*! @brief Returns smeared configuration at level 'Level' */ - const GaugeField& get_smeared_conf(int Level) const { + const GaugeField &get_smeared_conf(int Level) const + { return SmearedSet[Level]; } //==================================================================== - void set_iLambda(GaugeLinkField& iLambda, GaugeLinkField& e_iQ, - const GaugeLinkField& iQ, const GaugeLinkField& Sigmap, - const GaugeLinkField& GaugeK) const { - GridBase* grid = iQ._grid; + void set_iLambda(GaugeLinkField &iLambda, GaugeLinkField &e_iQ, + const GaugeLinkField &iQ, const GaugeLinkField &Sigmap, + const GaugeLinkField &GaugeK) const + { + GridBase *grid = iQ._grid; GaugeLinkField iQ2(grid), iQ3(grid), B1(grid), B2(grid), USigmap(grid); GaugeLinkField unity(grid); unity = 1.0; @@ -206,15 +217,15 @@ class SmearedConfiguration { } //==================================================================== - public: - GaugeField* - ThinLinks; /*!< @brief Pointer to the thin - links configuration */ +public: + GaugeField * + ThinLinks; /* Pointer to the thin links configuration */ - /*! @brief Standard constructor */ - SmearedConfiguration(GridCartesian* UGrid, unsigned int Nsmear, - Smear_Stout& Stout) - : smearingLevels(Nsmear), StoutSmearing(Stout), ThinLinks(NULL) { + /* Standard constructor */ + SmearedConfiguration(GridCartesian *UGrid, unsigned int Nsmear, + Smear_Stout &Stout) + : smearingLevels(Nsmear), StoutSmearing(Stout), ThinLinks(NULL) + { for (unsigned int i = 0; i < smearingLevels; ++i) SmearedSet.push_back(*(new GaugeField(UGrid))); } @@ -223,21 +234,29 @@ class SmearedConfiguration { SmearedConfiguration() : smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {} - - // attach the smeared routines to the thin links U and fill the smeared set - void set_Field(GaugeField& U) { fill_smearedSet(U); } + void set_Field(GaugeField &U) + { + double start = usecond(); + fill_smearedSet(U); + double end = usecond(); + double time = (stop - start)/ 1e3; + std::cout << GridLogMessage << "Smearing in " << time << " ms" << std::endl; + } //==================================================================== - void smeared_force(GaugeField& SigmaTilde) const { - if (smearingLevels > 0) { + void smeared_force(GaugeField &SigmaTilde) const + { + if (smearingLevels > 0) + { + double start = usecond(); GaugeField force = SigmaTilde; // actually = U*SigmaTilde GaugeLinkField tmp_mu(SigmaTilde._grid); - for (int mu = 0; mu < Nd; mu++) { + for (int mu = 0; mu < Nd; mu++) + { // to get just SigmaTilde - tmp_mu = adj(peekLorentz(SmearedSet[smearingLevels - 1], mu)) * - peekLorentz(force, mu); + tmp_mu = adj(peekLorentz(SmearedSet[smearingLevels - 1], mu)) * peekLorentz(force, mu); pokeLorentz(force, tmp_mu, mu); } @@ -246,33 +265,43 @@ class SmearedConfiguration { force = AnalyticSmearedForce(force, *ThinLinks); - for (int mu = 0; mu < Nd; mu++) { + for (int mu = 0; mu < Nd; mu++) + { tmp_mu = peekLorentz(*ThinLinks, mu) * peekLorentz(force, mu); pokeLorentz(SigmaTilde, tmp_mu, mu); } - } // if smearingLevels = 0 do nothing + double end = usecond(); + double time = (stop - start)/ 1e3; + std::cout << GridLogMessage << "Smearing force in " << time << " ms" << std::endl; + } // if smearingLevels = 0 do nothing } //==================================================================== - GaugeField& get_SmearedU() { return SmearedSet[smearingLevels - 1]; } + GaugeField &get_SmearedU() { return SmearedSet[smearingLevels - 1]; } - GaugeField& get_U(bool smeared = false) { + GaugeField &get_U(bool smeared = false) + { // get the config, thin links by default - if (smeared) { - if (smearingLevels) { + if (smeared) + { + if (smearingLevels) + { RealD impl_plaq = WilsonLoops::avgPlaquette(SmearedSet[smearingLevels - 1]); std::cout << GridLogDebug << "getting Usmr Plaq: " << impl_plaq << std::endl; return get_SmearedU(); - - } else { + } + else + { RealD impl_plaq = WilsonLoops::avgPlaquette(*ThinLinks); std::cout << GridLogDebug << "getting Thin Plaq: " << impl_plaq << std::endl; return *ThinLinks; } - } else { + } + else + { RealD impl_plaq = WilsonLoops::avgPlaquette(*ThinLinks); std::cout << GridLogDebug << "getting Thin Plaq: " << impl_plaq << std::endl; From 6358f35b7e93d36f1f9a4378ddd53cc2a88242be Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 26 Apr 2018 14:18:11 +0900 Subject: [PATCH 073/126] Debug of previous commit --- lib/qcd/smearing/GaugeConfiguration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/qcd/smearing/GaugeConfiguration.h b/lib/qcd/smearing/GaugeConfiguration.h index 55d5351f..6fea875b 100644 --- a/lib/qcd/smearing/GaugeConfiguration.h +++ b/lib/qcd/smearing/GaugeConfiguration.h @@ -240,7 +240,7 @@ public: double start = usecond(); fill_smearedSet(U); double end = usecond(); - double time = (stop - start)/ 1e3; + double time = (end - start)/ 1e3; std::cout << GridLogMessage << "Smearing in " << time << " ms" << std::endl; } @@ -271,7 +271,7 @@ public: pokeLorentz(SigmaTilde, tmp_mu, mu); } double end = usecond(); - double time = (stop - start)/ 1e3; + double time = (end - start)/ 1e3; std::cout << GridLogMessage << "Smearing force in " << time << " ms" << std::endl; } // if smearingLevels = 0 do nothing } From 8f44c799a69d3041f00af7b7785a268a914ed6c5 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Thu, 26 Apr 2018 14:48:03 +0100 Subject: [PATCH 074/126] Saving the benchmarking tests for Cshift --- benchmarks/Benchmark_su3.cc | 64 +++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index b31af942..656f816a 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -35,24 +35,25 @@ using namespace Grid::QCD; int main (int argc, char ** argv) { Grid_init(&argc,&argv); +#define LMIN (16) #define LMAX (40) -#define LINC (4) +#define LINC (8) - int64_t Nloop=20; + int64_t Nloop=200; std::vector simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd()); std::vector mpi_layout = GridDefaultMpi(); int64_t threads = GridThread::GetThreads(); std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -84,7 +85,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -115,7 +116,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -146,7 +147,7 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -170,7 +171,6 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; @@ -203,6 +203,52 @@ int main (int argc, char ** argv) std::cout< latt_size ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]}); + int64_t vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; + + GridCartesian Grid(latt_size,simd_layout,mpi_layout); + GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(std::vector({45,12,81,9})); + + LatticeColourMatrix z(&Grid); random(pRNG,z); + LatticeColourMatrix x(&Grid); random(pRNG,x); + LatticeColourMatrix y(&Grid); random(pRNG,y); + LatticeColourMatrix tmp(&Grid); + + for(int mu=0;mu<4;mu++){ + double tshift=0; + double tmult =0; + + double start=usecond(); + for(int64_t i=0;i Date: Thu, 26 Apr 2018 14:48:35 +0100 Subject: [PATCH 075/126] Improvement --- benchmarks/Benchmark_memory_bandwidth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/Benchmark_memory_bandwidth.cc b/benchmarks/Benchmark_memory_bandwidth.cc index 848f271d..cc965050 100644 --- a/benchmarks/Benchmark_memory_bandwidth.cc +++ b/benchmarks/Benchmark_memory_bandwidth.cc @@ -55,7 +55,7 @@ int main (int argc, char ** argv) std::cout< Date: Thu, 26 Apr 2018 14:48:57 +0100 Subject: [PATCH 076/126] Guard bare openmp statemetn with ifdef --- lib/allocator/AlignedAllocator.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/allocator/AlignedAllocator.h b/lib/allocator/AlignedAllocator.h index 3b27aec9..b0f7e206 100644 --- a/lib/allocator/AlignedAllocator.h +++ b/lib/allocator/AlignedAllocator.h @@ -277,7 +277,9 @@ public: uint8_t *cp = (uint8_t *)ptr; if ( ptr ) { // One touch per 4k page, static OMP loop to catch same loop order +#ifdef GRID_OMP #pragma omp parallel for schedule(static) +#endif for(size_type n=0;n Date: Thu, 26 Apr 2018 14:49:42 +0100 Subject: [PATCH 077/126] Force static --- lib/threads/Threads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/threads/Threads.h b/lib/threads/Threads.h index 36daf2af..dacaf5d8 100644 --- a/lib/threads/Threads.h +++ b/lib/threads/Threads.h @@ -40,7 +40,7 @@ Author: paboyle #define PARALLEL_FOR_LOOP _Pragma("omp parallel for schedule(static)") #define PARALLEL_FOR_LOOP_INTERN _Pragma("omp for schedule(static)") -#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)") +#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for schedule(static) collapse(2)") #define PARALLEL_REGION _Pragma("omp parallel") #define PARALLEL_CRITICAL _Pragma("omp critical") #else From 03e9832efa55892c00e028fd4601220c7378a13d Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Thu, 26 Apr 2018 14:50:02 +0100 Subject: [PATCH 078/126] Use macros for bare openmp --- lib/parallelIO/BinaryIO.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 45fd522e..ce84fc81 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -110,11 +110,11 @@ class BinaryIO { lsites = 1; } - #pragma omp parallel +PARALLEL_REGION { uint32_t nersc_csum_thr = 0; - #pragma omp for +PARALLEL_FOR_LOOP_INTERN for (uint64_t local_site = 0; local_site < lsites; local_site++) { uint32_t *site_buf = (uint32_t *)&fbuf[local_site]; @@ -124,7 +124,7 @@ class BinaryIO { } } - #pragma omp critical +PARALLEL_CRITICAL { nersc_csum += nersc_csum_thr; } @@ -146,14 +146,14 @@ class BinaryIO { std::vector local_start =grid->LocalStarts(); std::vector global_vol =grid->FullDimensions(); -#pragma omp parallel +PARALLEL_REGION { std::vector coor(nd); uint32_t scidac_csuma_thr=0; uint32_t scidac_csumb_thr=0; uint32_t site_crc=0; -#pragma omp for +PARALLEL_FOR_LOOP_INTERN for(uint64_t local_site=0;local_site>(32-gsite31); } -#pragma omp critical +PARALLEL_CRITICAL { scidac_csuma^= scidac_csuma_thr; scidac_csumb^= scidac_csumb_thr; From d47484717e91db165f8e1d35446689dd2400e067 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Thu, 26 Apr 2018 17:32:37 +0100 Subject: [PATCH 079/126] Hadrons: scalar SU(N) result handling improvement --- extras/Hadrons/Modules/MScalarSUN/Div.hpp | 17 +++--- extras/Hadrons/Modules/MScalarSUN/EMT.hpp | 35 ++++++++++- extras/Hadrons/Modules/MScalarSUN/Grad.hpp | 35 +++++------ .../Hadrons/Modules/MScalarSUN/ShiftProbe.hpp | 24 +++++--- .../Hadrons/Modules/MScalarSUN/TrKinetic.hpp | 60 ++++++++----------- extras/Hadrons/Modules/MScalarSUN/TrMag.hpp | 21 +++---- extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp | 22 +++---- .../Hadrons/Modules/MScalarSUN/TransProj.hpp | 42 ++++++------- .../Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 24 ++++---- 9 files changed, 156 insertions(+), 124 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/Div.hpp b/extras/Hadrons/Modules/MScalarSUN/Div.hpp index 1b59fbed..ff26c60b 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Div.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Div.hpp @@ -49,19 +49,20 @@ public: std::string, output); }; +class DivResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(DivResult, + DiffType, type, + Complex, value); +}; + template class TDiv: public Module { public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - DiffType, type, - Complex, value); - }; public: // constructor TDiv(const std::string name); @@ -139,7 +140,7 @@ void TDiv::execute(void) } if (!par().output.empty()) { - Result r; + DivResult r; r.type = par().type; r.value = TensorRemove(sum(div)); diff --git a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp index 025b7936..dbbfb6b3 100644 --- a/extras/Hadrons/Modules/MScalarSUN/EMT.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/EMT.hpp @@ -54,6 +54,17 @@ public: std::string, output); }; +class EMTResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(EMTResult, + std::vector>, value, + double, m2, + double, lambda, + double, g, + double, xi); +}; + template class TEMT: public Module { @@ -155,13 +166,22 @@ void TEMT::execute(void) LOG(Message) << " xi= " << par().xi << std::endl; } - const unsigned int N = SImpl::Group::Dimension; + const unsigned int N = SImpl::Group::Dimension, nd = env().getNd(); auto &trphi2 = envGet(ComplexField, varName(par().phiPow, 2)); auto &trphi4 = envGet(ComplexField, varName(par().phiPow, 4)); auto &sumkin = envGet(ComplexField, varName(par().kinetic, "sum")); + EMTResult result; - for (unsigned int mu = 0; mu < env().getNd(); ++mu) - for (unsigned int nu = mu; nu < env().getNd(); ++nu) + if (!par().output.empty()) + { + result.m2 = par().m2; + result.g = par().g; + result.lambda = par().lambda; + result.xi = par().xi; + result.value.resize(nd, std::vector(nd)); + } + for (unsigned int mu = 0; mu < nd; ++mu) + for (unsigned int nu = mu; nu < nd; ++nu) { auto &out = envGet(ComplexField, varName(getName(), mu, nu)); auto &trkin = envGet(ComplexField, varName(par().kinetic, mu, nu)); @@ -178,6 +198,15 @@ void TEMT::execute(void) out -= sumkin + par().m2*trphi2 + par().lambda*trphi4; } out *= N/par().g; + if (!par().output.empty()) + { + result.value[mu][nu] = TensorRemove(sum(out)); + result.value[mu][nu] = result.value[nu][mu]; + } + } + if (!par().output.empty()) + { + saveResult(par().output, "emt", result); } } diff --git a/extras/Hadrons/Modules/MScalarSUN/Grad.hpp b/extras/Hadrons/Modules/MScalarSUN/Grad.hpp index 7718fbf2..ecf65e90 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Grad.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Grad.hpp @@ -49,19 +49,20 @@ public: std::string, output); }; +class GradResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(GradResult, + DiffType, type, + std::vector, value); +}; + template class TGrad: public Module { public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - DiffType, type, - Complex, value); - }; public: // constructor TGrad(const std::string name); @@ -130,14 +131,18 @@ void TGrad::setup(void) template void TGrad::execute(void) { - const auto nd = env().getNd(); - LOG(Message) << "Computing the " << par().type << " gradient of '" << par().op << "'" << std::endl; - std::vector result; - auto &op = envGet(ComplexField, par().op); + const unsigned int nd = env().getNd(); + GradResult result; + auto &op = envGet(ComplexField, par().op); + if (!par().output.empty()) + { + result.type = par().type; + result.value.resize(nd); + } for (unsigned int mu = 0; mu < nd; ++mu) { auto &der = envGet(ComplexField, varName(getName(), mu)); @@ -145,14 +150,10 @@ void TGrad::execute(void) dmu(der, op, mu, par().type); if (!par().output.empty()) { - Result r; - - r.type = par().type; - r.value = TensorRemove(sum(der)); - result.push_back(r); + result.value[mu] = TensorRemove(sum(der)); } } - if (result.size() > 0) + if (!par().output.empty()) { saveResult(par().output, "grad", result); } diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp index c7c0e9ee..cd7c15eb 100644 --- a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp @@ -51,20 +51,20 @@ public: std::string, output); }; +class ShiftProbeResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(ShiftProbeResult, + std::string, shifts, + Complex, value); +}; + template class TShiftProbe: public Module { public: - typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - std::string, op, - Complex , value); - }; public: // constructor TShiftProbe(const std::string name); @@ -160,6 +160,14 @@ void TShiftProbe::execute(void) } } probe = real(sign*trace(acc)); + if (!par().output.empty()) + { + ShiftProbeResult r; + + r.shifts = par().shifts; + r.value = TensorRemove(sum(probe)); + saveResult(par().output, "probe", r); + } } END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp index 59aa27b8..a714daaa 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrKinetic.hpp @@ -49,19 +49,20 @@ public: std::string, output); }; +class TrKineticResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TrKineticResult, + std::vector>, value, + DiffType, type); +}; + template class TTrKinetic: public Module { public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - std::string, op, - Complex , value); - }; public: // constructor TTrKinetic(const std::string name); @@ -135,18 +136,24 @@ void TTrKinetic::execute(void) LOG(Message) << "Computing tr(d_mu phi*d_nu phi) using " << par().type << " derivative" << std::endl; - std::vector result; - auto &phi = envGet(Field, par().field); - auto &sumkin = envGet(ComplexField, varName(getName(), "sum")); + const unsigned int nd = env().getNd(); + TrKineticResult result; + auto &phi = envGet(Field, par().field); + auto &sumkin = envGet(ComplexField, varName(getName(), "sum")); envGetTmp(std::vector, der); sumkin = zero; - for (unsigned int mu = 0; mu < env().getNd(); ++mu) + if (!par().output.empty()) + { + result.type = par().type; + result.value.resize(nd, std::vector(nd)); + } + for (unsigned int mu = 0; mu < nd; ++mu) { dmu(der[mu], phi, mu, par().type); } - for (unsigned int mu = 0; mu < env().getNd(); ++mu) - for (unsigned int nu = mu; nu < env().getNd(); ++nu) + for (unsigned int mu = 0; mu < nd; ++mu) + for (unsigned int nu = mu; nu < nd; ++nu) { auto &out = envGet(ComplexField, varName(getName(), mu, nu)); @@ -155,32 +162,13 @@ void TTrKinetic::execute(void) { sumkin += out; } - } - if (!par().output.empty()) - { - for (unsigned int mu = 0; mu < env().getNd(); ++mu) - for (unsigned int nu = mu; nu < env().getNd(); ++nu) + if (!par().output.empty()) { - auto &out = envGet(ComplexField, varName(getName(), mu, nu)); - Result r; - - r.op = "tr(d_" + std::to_string(mu) + "phi*d_" - + std::to_string(nu) + "phi)"; - r.value = TensorRemove(sum(out)); - result.push_back(r); - } - { - Result r; - - r.op = "sum_mu tr(d_mu phi*d_mu phi)"; - r.value = TensorRemove(sum(sumkin)); - result.push_back(r); + result.value[mu][nu] = TensorRemove(sum(out)); + result.value[mu][nu] = result.value[nu][mu]; } } - if (result.size() > 0) - { - saveResult(par().output, "trkinetic", result); - } + saveResult(par().output, "trkinetic", result); } END_MODULE_NAMESPACE diff --git a/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp b/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp index ed1a629a..cdbf7e30 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrMag.hpp @@ -49,19 +49,20 @@ public: std::string, output); }; +class TrMagResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TrMagResult, + std::string, op, + Real, value); +}; + template class TTrMag: public Module { public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - std::string, op, - Real, value); - }; public: // constructor TTrMag(const std::string name); @@ -120,8 +121,8 @@ void TTrMag::execute(void) LOG(Message) << "Computing tr(mag^n) for n even up to " << par().maxPow << std::endl; - std::vector result; - auto &phi = envGet(Field, par().field); + std::vector result; + auto &phi = envGet(Field, par().field); auto m2 = sum(phi), mn = m2; @@ -129,7 +130,7 @@ void TTrMag::execute(void) mn = 1.; for (unsigned int n = 2; n <= par().maxPow; n += 2) { - Result r; + TrMagResult r; mn = mn*m2; r.op = "tr(mag^" + std::to_string(n) + ")"; diff --git a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp index 6c1d733b..9be0a5d6 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TrPhi.hpp @@ -49,19 +49,21 @@ public: std::string, output); }; +class TrPhiResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TrPhiResult, + std::string, op, + Real, value); +}; + template class TTrPhi: public Module { public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - std::string, op, - Real, value); - }; + public: // constructor TTrPhi(const std::string name); @@ -136,8 +138,8 @@ void TTrPhi::execute(void) LOG(Message) << "Computing tr(phi^n) for n even up to " << par().maxPow << std::endl; - std::vector result; - auto &phi = envGet(Field, par().field); + std::vector result; + auto &phi = envGet(Field, par().field); envGetTmp(Field, phi2); envGetTmp(Field, buf); @@ -151,7 +153,7 @@ void TTrPhi::execute(void) phin = trace(buf); if (!par().output.empty()) { - Result r; + TrPhiResult r; r.op = "tr(phi^" + std::to_string(n) + ")"; r.value = TensorRemove(sum(phin)).real(); diff --git a/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp b/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp index 6c6502fc..c9b42bf0 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TransProj.hpp @@ -49,19 +49,20 @@ public: std::string, output); }; +class TransProjResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TransProjResult, + std::vector>, value, + DiffType, type); +}; + template class TTransProj: public Module { public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - std::string, op, - Complex , value); - }; public: // constructor TTransProj(const std::string name); @@ -137,21 +138,27 @@ void TTransProj::execute(void) << par().type << " derivatives and op= '" << par().op << "'" << std::endl; - std::vector result; - auto &op = envGet(ComplexField, par().op); + const unsigned int nd = env().getNd(); + TransProjResult result; + auto &op = envGet(ComplexField, par().op); envGetTmp(ComplexField, buf1); envGetTmp(ComplexField, buf2); envGetTmp(ComplexField, lap); lap = zero; - for (unsigned int mu = 0; mu < env().getNd(); ++mu) + if (!par().output.empty()) + { + result.type = par().type; + result.value.resize(nd, std::vector(nd)); + } + for (unsigned int mu = 0; mu < nd; ++mu) { dmu(buf1, op, mu, par().type); dmu(buf2, buf1, mu, par().type); lap += buf2; } - for (unsigned int mu = 0; mu < env().getNd(); ++mu) - for (unsigned int nu = mu; nu < env().getNd(); ++nu) + for (unsigned int mu = 0; mu < nd; ++mu) + for (unsigned int nu = mu; nu < nd; ++nu) { auto &out = envGet(ComplexField, varName(getName(), mu, nu)); dmu(buf1, op, mu, par().type); @@ -163,16 +170,11 @@ void TTransProj::execute(void) } if (!par().output.empty()) { - Result r; - - r.op = "(delta_" + std::to_string(mu) + "," + std::to_string(nu) - + " d^2 - d_" + std::to_string(mu) + "*d_" - + std::to_string(nu) + ")*op"; - r.value = TensorRemove(sum(out)); - result.push_back(r); + result.value[mu][nu] = TensorRemove(sum(out)); + result.value[mu][nu] = result.value[nu][mu]; } } - if (result.size() > 0) + if (!par().output.empty()) { saveResult(par().output, "transproj", result); } diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index 9e53553f..abca6212 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -50,6 +50,16 @@ public: std::string, output); }; +class TwoPointResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TwoPointResult, + std::string, sink, + std::string, source, + std::vector, mom, + std::vector, data); +}; + template class TTwoPoint: public Module { @@ -57,16 +67,6 @@ public: typedef typename SImpl::Field Field; typedef typename SImpl::ComplexField ComplexField; typedef std::vector SlicedOp; - - class Result: Serializable - { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(Result, - std::string, sink, - std::string, source, - std::vector, mom, - std::vector, data); - }; public: // constructor TTwoPoint(const std::string name); @@ -166,7 +166,7 @@ void TTwoPoint::execute(void) const unsigned int nmom = mom_.size(); std::vector dMask(nd, 1); std::set ops; - std::vector result; + std::vector result; std::map> slicedOp; FFT fft(env().getGrid()); @@ -201,7 +201,7 @@ void TTwoPoint::execute(void) for (unsigned int m = 0; m < nmom; ++m) for (auto &p: par().op) { - Result r; + TwoPointResult r; r.sink = p.first; r.source = p.second; From fa0d8feff421001740acf3a1d039ec3e86980164 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Thu, 26 Apr 2018 17:56:27 +0100 Subject: [PATCH 080/126] Performance of CovariantCshift now non-embarrassing. --- benchmarks/Benchmark_su3.cc | 6 +-- lib/cshift/Cshift_common.h | 93 ++++++++++++++++++++++--------------- lib/lattice/Lattice_base.h | 3 +- 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/benchmarks/Benchmark_su3.cc b/benchmarks/Benchmark_su3.cc index 7e5436b1..7b1b2c1a 100644 --- a/benchmarks/Benchmark_su3.cc +++ b/benchmarks/Benchmark_su3.cc @@ -36,7 +36,7 @@ int main (int argc, char ** argv) { Grid_init(&argc,&argv); #define LMAX (32) -#define LMIN (4) +#define LMIN (16) #define LINC (4) int64_t Nloop=2000; @@ -204,7 +204,7 @@ int main (int argc, char ** argv) std::cout< &rhs,commVector &buffer,int dimen int so=plane*rhs._grid->_ostride[dimension]; // base offset for start of plane int e1=rhs._grid->_slice_nblock[dimension]; int e2=rhs._grid->_slice_block[dimension]; + int ent = 0; + + static std::vector > table; table.resize(e1*e2); int stride=rhs._grid->_slice_stride[dimension]; if ( cbmask == 0x3 ) { - parallel_for_nest2(int n=0;n(off+bo+b,so+o+b); } } } else { int bo=0; - std::vector > table; for(int n=0;nCheckerBoardFromOindex(o+b); if ( ocb &cbmask ) { - table.push_back(std::pair (bo++,o+b)); + table[ent++]=std::pair (off+bo++,so+o+b); } } } - parallel_for(int i=0;i void Scatter_plane_simple (Lattice &rhs,commVector_slice_nblock[dimension]; int e2=rhs._grid->_slice_block[dimension]; int stride=rhs._grid->_slice_stride[dimension]; - + + static std::vector > table; table.resize(e1*e2); + int ent =0; + if ( cbmask ==0x3 ) { - parallel_for_nest2(int n=0;n_slice_stride[dimension]; int bo =n*rhs._grid->_slice_block[dimension]; - rhs._odata[so+o+b]=buffer[bo+b]; + table[ent++] = std::pair(so+o+b,bo); } } + } else { - std::vector > table; int bo=0; for(int n=0;n_slice_stride[dimension]; int ocb=1<CheckerBoardFromOindex(o+b);// Could easily be a table lookup if ( ocb & cbmask ) { - table.push_back(std::pair (so+o+b,bo++)); + table[ent++]=std::pair (so+o+b,bo++); } } } - parallel_for(int i=0;i void Copy_plane(Lattice& lhs,const Lattice &rhs int e1=rhs._grid->_slice_nblock[dimension]; // clearly loop invariant for icpc int e2=rhs._grid->_slice_block[dimension]; int stride = rhs._grid->_slice_stride[dimension]; + static std::vector > table; table.resize(e1*e2); + int ent=0; + if(cbmask == 0x3 ){ - parallel_for_nest2(int n=0;n(lo+o,ro+o); } } } else { - parallel_for_nest2(int n=0;nCheckerBoardFromOindex(o); if ( ocb&cbmask ) { - //lhs._odata[lo+o]=rhs._odata[ro+o]; - vstream(lhs._odata[lo+o],rhs._odata[ro+o]); + table[ent++] = std::pair(lo+o,ro+o); } } } } - + + parallel_for(int i=0;i void Copy_plane_permute(Lattice& lhs,const Lattice &rhs, int dimension,int lplane,int rplane,int cbmask,int permute_type) @@ -269,16 +278,28 @@ template void Copy_plane_permute(Lattice& lhs,const Lattice_slice_block [dimension]; int stride = rhs._grid->_slice_stride[dimension]; - parallel_for_nest2(int n=0;n > table; table.resize(e1*e2); + int ent=0; + double t_tab,t_perm; + if ( cbmask == 0x3 ) { + for(int n=0;n(lo+o+b,ro+o+b); + }} + } else { + for(int n=0;nCheckerBoardFromOindex(o+b); - if ( ocb&cbmask ) { - permute(lhs._odata[lo+o+b],rhs._odata[ro+o+b],permute_type); - } + if ( ocb&cbmask ) table[ent++] = std::pair(lo+o+b,ro+o+b); + }} + } - }} + parallel_for(int i=0;i void Cshift_local(Lattice& ret,const Lattice &r sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even); sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd); + double t_local; + if ( sshift[0] == sshift[1] ) { Cshift_local(ret,rhs,dimension,shift,0x3); } else { @@ -299,7 +322,7 @@ template void Cshift_local(Lattice& ret,const Lattice &r } } -template Lattice Cshift_local(Lattice &ret,const Lattice &rhs,int dimension,int shift,int cbmask) +template void Cshift_local(Lattice &ret,const Lattice &rhs,int dimension,int shift,int cbmask) { GridBase *grid = rhs._grid; int fd = grid->_fdimensions[dimension]; @@ -325,11 +348,7 @@ template Lattice Cshift_local(Lattice &ret,const Lattice int sshift = grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb); int sx = (x+sshift)%rd; - - // FIXME : This must change where we have a - // Rotate slice. - // Document how this works ; why didn't I do this when I first wrote it... // wrap is whether sshift > rd. // num is sshift mod rd. // @@ -365,10 +384,8 @@ template Lattice Cshift_local(Lattice &ret,const Lattice if ( permute_slice ) Copy_plane_permute(ret,rhs,dimension,x,sx,cbmask,permute_type_dist); else Copy_plane(ret,rhs,dimension,x,sx,cbmask); - } - return ret; } } #endif diff --git a/lib/lattice/Lattice_base.h b/lib/lattice/Lattice_base.h index 98713c14..1169d18f 100644 --- a/lib/lattice/Lattice_base.h +++ b/lib/lattice/Lattice_base.h @@ -256,7 +256,7 @@ public: _odata[ss]=r._odata[ss]; } } - + Lattice(Lattice&& r){ // move constructor _grid = r._grid; checkerboard = r.checkerboard; @@ -270,6 +270,7 @@ public: _odata =std::move(r._odata); return *this; } + inline Lattice & operator = (const Lattice & r){ _grid = r._grid; checkerboard = r.checkerboard; From e9f1ac09ded186335c465b54bed60f3a44477ab9 Mon Sep 17 00:00:00 2001 From: paboyle Date: Thu, 26 Apr 2018 23:00:08 +0100 Subject: [PATCH 081/126] static --- lib/threads/Threads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/threads/Threads.h b/lib/threads/Threads.h index 36daf2af..dacaf5d8 100644 --- a/lib/threads/Threads.h +++ b/lib/threads/Threads.h @@ -40,7 +40,7 @@ Author: paboyle #define PARALLEL_FOR_LOOP _Pragma("omp parallel for schedule(static)") #define PARALLEL_FOR_LOOP_INTERN _Pragma("omp for schedule(static)") -#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)") +#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for schedule(static) collapse(2)") #define PARALLEL_REGION _Pragma("omp parallel") #define PARALLEL_CRITICAL _Pragma("omp critical") #else From 7ecc47ac89ddb310583fe5b548fd0804dfb6e0ce Mon Sep 17 00:00:00 2001 From: paboyle Date: Thu, 26 Apr 2018 23:00:28 +0100 Subject: [PATCH 082/126] Quenched test compile --- lib/lattice/Lattice_comparison_utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lattice/Lattice_comparison_utils.h b/lib/lattice/Lattice_comparison_utils.h index 9580d4d2..579449f1 100644 --- a/lib/lattice/Lattice_comparison_utils.h +++ b/lib/lattice/Lattice_comparison_utils.h @@ -198,7 +198,7 @@ namespace Grid { typedef typename vsimd::scalar_type scalar;\ return Comparison(functor(),lhs,rhs);\ }\ - template = 0>\ + template\ inline vInteger operator op(const iScalar &lhs,const iScalar &rhs)\ { \ return lhs._internal op rhs._internal; \ @@ -212,7 +212,7 @@ namespace Grid { inline vInteger operator op(const typename vsimd::scalar_type &lhs,const iScalar &rhs) \ { \ return lhs op rhs._internal; \ - } + } \ DECLARE_RELATIONAL(<,slt); From 1be80896048e42c825f81a6bc5a26d79c537f37d Mon Sep 17 00:00:00 2001 From: paboyle Date: Thu, 26 Apr 2018 23:42:45 +0100 Subject: [PATCH 083/126] Clean compile --- lib/lattice/Lattice_comparison_utils.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/lattice/Lattice_comparison_utils.h b/lib/lattice/Lattice_comparison_utils.h index 579449f1..cbac20ec 100644 --- a/lib/lattice/Lattice_comparison_utils.h +++ b/lib/lattice/Lattice_comparison_utils.h @@ -179,7 +179,7 @@ namespace Grid { return ret; } -#define DECLARE_RELATIONAL(op,functor) \ +#define DECLARE_RELATIONAL_EQ(op,functor) \ template = 0>\ inline vInteger operator op (const vsimd & lhs, const vsimd & rhs)\ {\ @@ -198,11 +198,6 @@ namespace Grid { typedef typename vsimd::scalar_type scalar;\ return Comparison(functor(),lhs,rhs);\ }\ - template\ - inline vInteger operator op(const iScalar &lhs,const iScalar &rhs)\ - { \ - return lhs._internal op rhs._internal; \ - } \ template\ inline vInteger operator op(const iScalar &lhs,const typename vsimd::scalar_type &rhs) \ { \ @@ -214,12 +209,19 @@ namespace Grid { return lhs op rhs._internal; \ } \ +#define DECLARE_RELATIONAL(op,functor) \ + DECLARE_RELATIONAL_EQ(op,functor) \ + template\ + inline vInteger operator op(const iScalar &lhs,const iScalar &rhs)\ + { \ + return lhs._internal op rhs._internal; \ + } DECLARE_RELATIONAL(<,slt); DECLARE_RELATIONAL(<=,sle); DECLARE_RELATIONAL(>,sgt); DECLARE_RELATIONAL(>=,sge); -DECLARE_RELATIONAL(==,seq); +DECLARE_RELATIONAL_EQ(==,seq); DECLARE_RELATIONAL(!=,sne); #undef DECLARE_RELATIONAL From 809b1cdd58d33ca43cab460a838589dfd0f2ce78 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 27 Apr 2018 05:19:10 +0100 Subject: [PATCH 084/126] Bug fix for MPI running ; introduced last night --- lib/cshift/Cshift_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cshift/Cshift_common.h b/lib/cshift/Cshift_common.h index b2f87315..24e0d2ab 100644 --- a/lib/cshift/Cshift_common.h +++ b/lib/cshift/Cshift_common.h @@ -152,7 +152,7 @@ template void Scatter_plane_simple (Lattice &rhs,commVector_slice_stride[dimension]; int bo =n*rhs._grid->_slice_block[dimension]; - table[ent++] = std::pair(so+o+b,bo); + table[ent++] = std::pair(so+o+b,bo+b); } } From 0734e9ddd4a24e4d7d1ee7224568105cfd39ac5b Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 27 Apr 2018 14:39:01 +0900 Subject: [PATCH 085/126] Debugging Scatter_plane_simple --- lib/cshift/Cshift_common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/cshift/Cshift_common.h b/lib/cshift/Cshift_common.h index b2f87315..c9faf365 100644 --- a/lib/cshift/Cshift_common.h +++ b/lib/cshift/Cshift_common.h @@ -150,9 +150,9 @@ template void Scatter_plane_simple (Lattice &rhs,commVector_slice_stride[dimension]; - int bo =n*rhs._grid->_slice_block[dimension]; - table[ent++] = std::pair(so+o+b,bo); + int o =n*rhs._grid->_slice_stride[dimension]; + int bo =n*rhs._grid->_slice_block[dimension]; + table[ent++] = std::pair(so+o+b,bo+b); } } From 75e4483407fe4f9f9715f06ba6e95be4c9eef2b8 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 27 Apr 2018 07:49:57 +0100 Subject: [PATCH 086/126] Stronger convergence test --- .../iterative/ImplicitlyRestartedLanczos.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/algorithms/iterative/ImplicitlyRestartedLanczos.h b/lib/algorithms/iterative/ImplicitlyRestartedLanczos.h index 787cf15a..8011e796 100644 --- a/lib/algorithms/iterative/ImplicitlyRestartedLanczos.h +++ b/lib/algorithms/iterative/ImplicitlyRestartedLanczos.h @@ -479,15 +479,13 @@ until convergence Field B(grid); B.checkerboard = evec[0].checkerboard; // power of two search pattern; not every evalue in eval2 is assessed. + int allconv =1; for(int jj = 1; jj<=Nstop; jj*=2){ int j = Nstop-jj; RealD e = eval2_copy[j]; // Discard the evalue basisRotateJ(B,evec,Qt,j,0,Nk,Nm); - if( _Tester.TestConvergence(j,eresid,B,e,evalMaxApprox) ) { - if ( j > Nconv ) { - Nconv=j+1; - jj=Nstop; // Terminate the scan - } + if( !_Tester.TestConvergence(j,eresid,B,e,evalMaxApprox) ) { + allconv=0; } } // Do evec[0] for good measure @@ -495,8 +493,10 @@ until convergence int j=0; RealD e = eval2_copy[0]; basisRotateJ(B,evec,Qt,j,0,Nk,Nm); - _Tester.TestConvergence(j,eresid,B,e,evalMaxApprox); + if( !_Tester.TestConvergence(j,eresid,B,e,evalMaxApprox) ) allconv=0; } + if ( allconv ) Nconv = Nstop; + // test if we converged, if so, terminate std::cout<= "<=Nstop || beta_k < betastp){ From b27f0e5a539fc59214d026d04143e67d2d5a0264 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 27 Apr 2018 07:50:15 +0100 Subject: [PATCH 087/126] Control over IO --- lib/algorithms/iterative/LocalCoherenceLanczos.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/algorithms/iterative/LocalCoherenceLanczos.h b/lib/algorithms/iterative/LocalCoherenceLanczos.h index b8348c0c..54e4c6c8 100644 --- a/lib/algorithms/iterative/LocalCoherenceLanczos.h +++ b/lib/algorithms/iterative/LocalCoherenceLanczos.h @@ -48,6 +48,7 @@ struct LanczosParams : Serializable { struct LocalCoherenceLanczosParams : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(LocalCoherenceLanczosParams, + bool, saveEvecs, bool, doFine, bool, doFineRead, bool, doCoarse, From 9b0240d1016c071750aefd28dbfbd97b781a8229 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 27 Apr 2018 07:50:51 +0100 Subject: [PATCH 088/126] Hot start test --- tests/Test_compressed_lanczos_hot_start.cc | 243 +++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 tests/Test_compressed_lanczos_hot_start.cc diff --git a/tests/Test_compressed_lanczos_hot_start.cc b/tests/Test_compressed_lanczos_hot_start.cc new file mode 100644 index 00000000..998f1b9f --- /dev/null +++ b/tests/Test_compressed_lanczos_hot_start.cc @@ -0,0 +1,243 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./tests/Test_dwf_compressed_lanczos_reorg.cc + + Copyright (C) 2017 + +Author: Leans heavily on Christoph Lehner's code +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 */ +/* + * Reimplement the badly named "multigrid" lanczos as compressed Lanczos using the features + * in Grid that were intended to be used to support blocked Aggregates, from + */ +#include +#include +#include + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +template +class LocalCoherenceLanczosScidac : public LocalCoherenceLanczos +{ +public: + typedef iVector CoarseSiteVector; + typedef Lattice CoarseField; + typedef Lattice CoarseScalar; // used for inner products on fine field + typedef Lattice FineField; + + LocalCoherenceLanczosScidac(GridBase *FineGrid,GridBase *CoarseGrid, + LinearOperatorBase &FineOp, + int checkerboard) + // Base constructor + : LocalCoherenceLanczos(FineGrid,CoarseGrid,FineOp,checkerboard) + {}; + + void checkpointFine(std::string evecs_file,std::string evals_file) + { + assert(this->subspace.size()==nbasis); + emptyUserRecord record; + Grid::QCD::ScidacWriter WR(this->_FineGrid->IsBoss()); + WR.open(evecs_file); + for(int k=0;ksubspace[k],record); + } + WR.close(); + + XmlWriter WRx(evals_file); + write(WRx,"evals",this->evals_fine); + } + + void checkpointFineRestore(std::string evecs_file,std::string evals_file) + { + this->evals_fine.resize(nbasis); + this->subspace.resize(nbasis,this->_FineGrid); + + std::cout << GridLogIRL<< "checkpointFineRestore: Reading evals from "<evals_fine); + + assert(this->evals_fine.size()==nbasis); + + std::cout << GridLogIRL<< "checkpointFineRestore: Reading evecs from "<subspace[k].checkerboard=this->_checkerboard; + RD.readScidacFieldRecord(this->subspace[k],record); + + } + RD.close(); + } + + void checkpointCoarse(std::string evecs_file,std::string evals_file) + { + int n = this->evec_coarse.size(); + emptyUserRecord record; + Grid::QCD::ScidacWriter WR(this->_CoarseGrid->IsBoss()); + WR.open(evecs_file); + for(int k=0;kevec_coarse[k],record); + } + WR.close(); + + XmlWriter WRx(evals_file); + write(WRx,"evals",this->evals_coarse); + } + + void checkpointCoarseRestore(std::string evecs_file,std::string evals_file,int nvec) + { + std::cout << "resizing coarse vecs to " << nvec<< std::endl; + this->evals_coarse.resize(nvec); + this->evec_coarse.resize(nvec,this->_CoarseGrid); + std::cout << GridLogIRL<< "checkpointCoarseRestore: Reading evals from "<evals_coarse); + + assert(this->evals_coarse.size()==nvec); + emptyUserRecord record; + std::cout << GridLogIRL<< "checkpointCoarseRestore: Reading evecs from "<evec_coarse[k],record); + } + RD.close(); + } +}; + +int main (int argc, char ** argv) { + + Grid_init(&argc,&argv); + GridLogIRL.TimingMode(1); + + LocalCoherenceLanczosParams Params; + { + Params.omega.resize(10); + Params.blockSize.resize(5); + XmlWriter writer("Params_template.xml"); + write(writer,"Params",Params); + std::cout << GridLogMessage << " Written Params_template.xml" < blockSize = Params.blockSize; + std::vector latt({16,16,16,16}); + uint64_t vol = Ls*latt[0]*latt[1]*latt[2]*latt[3]; + double mat_flop= 2.0*1320.0*vol; + // Grids + GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(latt, + GridDefaultSimd(Nd,vComplex::Nsimd()), + GridDefaultMpi()); + GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); + GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); + + std::vector fineLatt = latt; + int dims=fineLatt.size(); + assert(blockSize.size()==dims+1); + std::vector coarseLatt(dims); + std::vector coarseLatt5d ; + + for (int d=0;d seeds4({1,2,3,4}); + GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); + LatticeGaugeField Umu(UGrid); + SU3::HotConfiguration(RNG4,Umu); + // FieldMetaData header; + // NerscIO::readConfiguration(Umu,header,Params.config); + + std::cout << GridLogMessage << "Lattice dimensions: " << latt << " Ls: " << Ls << std::endl; + + // ZMobius EO Operator + ZMobiusFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mass, M5, Params.omega,1.,0.); + SchurDiagTwoOperator HermOp(Ddwf); + + // Eigenvector storage + LanczosParams fine =Params.FineParams; + LanczosParams coarse=Params.CoarseParams; + + const int Ns1 = fine.Nstop; const int Ns2 = coarse.Nstop; + const int Nk1 = fine.Nk; const int Nk2 = coarse.Nk; + const int Nm1 = fine.Nm; const int Nm2 = coarse.Nm; + + std::cout << GridLogMessage << "Keep " << fine.Nstop << " fine vectors" << std::endl; + std::cout << GridLogMessage << "Keep " << coarse.Nstop << " coarse vectors" << std::endl; + assert(Nm2 >= Nm1); + + const int nbasis= 60; + assert(nbasis==Ns1); + LocalCoherenceLanczosScidac _LocalCoherenceLanczos(FrbGrid,CoarseGrid5,HermOp,Odd); + std::cout << GridLogMessage << "Constructed LocalCoherenceLanczos" << std::endl; + + assert( (Params.doFine)||(Params.doFineRead)); + + if ( Params.doFine ) { + std::cout << GridLogMessage << "Performing fine grid IRL Nstop "<< Ns1 << " Nk "< Date: Fri, 27 Apr 2018 07:51:12 +0100 Subject: [PATCH 089/126] Roll over version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bfad377d..a0211af1 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -Version : 0.7.0 +Version : 0.8.0 - Clang 3.5 and above, ICPC v16 and above, GCC 6.3 and above recommended - MPI and MPI3 comms optimisations for KNL and OPA finished From e369d7306d8bc53fb1e2456152d444b7e61fda07 Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 27 Apr 2018 07:51:44 +0100 Subject: [PATCH 090/126] Rename --- tests/lanczos/Test_compressed_lanczos.cc | 253 +++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 tests/lanczos/Test_compressed_lanczos.cc diff --git a/tests/lanczos/Test_compressed_lanczos.cc b/tests/lanczos/Test_compressed_lanczos.cc new file mode 100644 index 00000000..8bce82bb --- /dev/null +++ b/tests/lanczos/Test_compressed_lanczos.cc @@ -0,0 +1,253 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./tests/Test_dwf_compressed_lanczos_reorg.cc + + Copyright (C) 2017 + +Author: Leans heavily on Christoph Lehner's code +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 */ +/* + * Reimplement the badly named "multigrid" lanczos as compressed Lanczos using the features + * in Grid that were intended to be used to support blocked Aggregates, from + */ +#include +#include +#include + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +template +class LocalCoherenceLanczosScidac : public LocalCoherenceLanczos +{ +public: + typedef iVector CoarseSiteVector; + typedef Lattice CoarseField; + typedef Lattice CoarseScalar; // used for inner products on fine field + typedef Lattice FineField; + + LocalCoherenceLanczosScidac(GridBase *FineGrid,GridBase *CoarseGrid, + LinearOperatorBase &FineOp, + int checkerboard) + // Base constructor + : LocalCoherenceLanczos(FineGrid,CoarseGrid,FineOp,checkerboard) + {}; + + void checkpointFine(std::string evecs_file,std::string evals_file) + { + assert(this->subspace.size()==nbasis); + emptyUserRecord record; + Grid::QCD::ScidacWriter WR(this->_FineGrid->IsBoss()); + WR.open(evecs_file); + for(int k=0;ksubspace[k],record); + } + WR.close(); + + XmlWriter WRx(evals_file); + write(WRx,"evals",this->evals_fine); + } + + void checkpointFineRestore(std::string evecs_file,std::string evals_file) + { + this->evals_fine.resize(nbasis); + this->subspace.resize(nbasis,this->_FineGrid); + + std::cout << GridLogIRL<< "checkpointFineRestore: Reading evals from "<evals_fine); + + assert(this->evals_fine.size()==nbasis); + + std::cout << GridLogIRL<< "checkpointFineRestore: Reading evecs from "<subspace[k].checkerboard=this->_checkerboard; + RD.readScidacFieldRecord(this->subspace[k],record); + + } + RD.close(); + } + + void checkpointCoarse(std::string evecs_file,std::string evals_file) + { + int n = this->evec_coarse.size(); + emptyUserRecord record; + Grid::QCD::ScidacWriter WR(this->_CoarseGrid->IsBoss()); + WR.open(evecs_file); + for(int k=0;kevec_coarse[k],record); + } + WR.close(); + + XmlWriter WRx(evals_file); + write(WRx,"evals",this->evals_coarse); + } + + void checkpointCoarseRestore(std::string evecs_file,std::string evals_file,int nvec) + { + std::cout << "resizing coarse vecs to " << nvec<< std::endl; + this->evals_coarse.resize(nvec); + this->evec_coarse.resize(nvec,this->_CoarseGrid); + std::cout << GridLogIRL<< "checkpointCoarseRestore: Reading evals from "<evals_coarse); + + assert(this->evals_coarse.size()==nvec); + emptyUserRecord record; + std::cout << GridLogIRL<< "checkpointCoarseRestore: Reading evecs from "<evec_coarse[k],record); + } + RD.close(); + } +}; + +int main (int argc, char ** argv) { + + Grid_init(&argc,&argv); + GridLogIRL.TimingMode(1); + + LocalCoherenceLanczosParams Params; + { + Params.omega.resize(10); + Params.blockSize.resize(5); + XmlWriter writer("Params_template.xml"); + write(writer,"Params",Params); + std::cout << GridLogMessage << " Written Params_template.xml" < blockSize = Params.blockSize; + + // Grids + GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), + GridDefaultSimd(Nd,vComplex::Nsimd()), + GridDefaultMpi()); + GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); + GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); + + std::vector fineLatt = GridDefaultLatt(); + int dims=fineLatt.size(); + assert(blockSize.size()==dims+1); + std::vector coarseLatt(dims); + std::vector coarseLatt5d ; + + for (int d=0;d HermOp(Ddwf); + + // Eigenvector storage + LanczosParams fine =Params.FineParams; + LanczosParams coarse=Params.CoarseParams; + + const int Ns1 = fine.Nstop; const int Ns2 = coarse.Nstop; + const int Nk1 = fine.Nk; const int Nk2 = coarse.Nk; + const int Nm1 = fine.Nm; const int Nm2 = coarse.Nm; + + std::cout << GridLogMessage << "Keep " << fine.Nstop << " fine vectors" << std::endl; + std::cout << GridLogMessage << "Keep " << coarse.Nstop << " coarse vectors" << std::endl; + assert(Nm2 >= Nm1); + + const int nbasis= 60; + assert(nbasis==Ns1); + LocalCoherenceLanczosScidac _LocalCoherenceLanczos(FrbGrid,CoarseGrid5,HermOp,Odd); + std::cout << GridLogMessage << "Constructed LocalCoherenceLanczos" << std::endl; + + assert( (Params.doFine)||(Params.doFineRead)); + + if ( Params.doFine ) { + std::cout << GridLogMessage << "Performing fine grid IRL Nstop "<< Ns1 << " Nk "< Date: Fri, 27 Apr 2018 08:57:34 +0100 Subject: [PATCH 091/126] Update with LIME library guard --- tests/Test_compressed_lanczos_hot_start.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/Test_compressed_lanczos_hot_start.cc b/tests/Test_compressed_lanczos_hot_start.cc index 998f1b9f..3276d0f8 100644 --- a/tests/Test_compressed_lanczos_hot_start.cc +++ b/tests/Test_compressed_lanczos_hot_start.cc @@ -56,6 +56,7 @@ public: void checkpointFine(std::string evecs_file,std::string evals_file) { +#ifdef HAVE_LIME assert(this->subspace.size()==nbasis); emptyUserRecord record; Grid::QCD::ScidacWriter WR(this->_FineGrid->IsBoss()); @@ -67,10 +68,14 @@ public: XmlWriter WRx(evals_file); write(WRx,"evals",this->evals_fine); +#else + assert(0); +#endif } void checkpointFineRestore(std::string evecs_file,std::string evals_file) { +#ifdef HAVE_LIME this->evals_fine.resize(nbasis); this->subspace.resize(nbasis,this->_FineGrid); @@ -90,10 +95,14 @@ public: } RD.close(); +#else + assert(0); +#endif } void checkpointCoarse(std::string evecs_file,std::string evals_file) { +#ifdef HAVE_LIME int n = this->evec_coarse.size(); emptyUserRecord record; Grid::QCD::ScidacWriter WR(this->_CoarseGrid->IsBoss()); @@ -105,10 +114,14 @@ public: XmlWriter WRx(evals_file); write(WRx,"evals",this->evals_coarse); +#else + assert(0); +#endif } void checkpointCoarseRestore(std::string evecs_file,std::string evals_file,int nvec) { +#ifdef HAVE_LIME std::cout << "resizing coarse vecs to " << nvec<< std::endl; this->evals_coarse.resize(nvec); this->evec_coarse.resize(nvec,this->_CoarseGrid); @@ -125,6 +138,9 @@ public: RD.readScidacFieldRecord(this->evec_coarse[k],record); } RD.close(); +#else + assert(0); +#endif } }; From 1dddd17e3c73c37bf769ad31532e44cbb0cdc585 Mon Sep 17 00:00:00 2001 From: Dr Peter Boyle Date: Fri, 27 Apr 2018 11:44:46 +0100 Subject: [PATCH 092/126] Benchmark improvements from tesseract --- benchmarks/Benchmark_ITT.cc | 13 ++++++++++--- benchmarks/Benchmark_comms.cc | 13 +++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/benchmarks/Benchmark_ITT.cc b/benchmarks/Benchmark_ITT.cc index 666e4830..f811ac32 100644 --- a/benchmarks/Benchmark_ITT.cc +++ b/benchmarks/Benchmark_ITT.cc @@ -158,8 +158,10 @@ public: dbytes=0; ncomm=0; - - parallel_for(int dir=0;dir<8;dir++){ +#ifdef GRID_OMP +#pragma omp parallel for num_threads(Grid::CartesianCommunicator::nCommThreads) +#endif + for(int dir=0;dir<8;dir++){ double tbytes; int mu =dir % 4; @@ -175,9 +177,14 @@ public: int comm_proc = mpi_layout[mu]-1; Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank); } +#ifdef GRID_OMP + int tid = omp_get_thread_num(); +#else + int tid = dir; +#endif tbytes= Grid.StencilSendToRecvFrom((void *)&xbuf[dir][0], xmit_to_rank, (void *)&rbuf[dir][0], recv_from_rank, - bytes,dir); + bytes,tid); #ifdef GRID_OMP #pragma omp atomic diff --git a/benchmarks/Benchmark_comms.cc b/benchmarks/Benchmark_comms.cc index 29ccf96c..304a09fc 100644 --- a/benchmarks/Benchmark_comms.cc +++ b/benchmarks/Benchmark_comms.cc @@ -169,7 +169,11 @@ int main (int argc, char ** argv) for(int lat=4;lat<=maxlat;lat+=4){ for(int Ls=8;Ls<=8;Ls*=2){ - std::vector latt_size ({lat,lat,lat,lat}); + std::vector latt_size ({lat*mpi_layout[0], + lat*mpi_layout[1], + lat*mpi_layout[2], + lat*mpi_layout[3]}); + GridCartesian Grid(latt_size,simd_layout,mpi_layout); RealD Nrank = Grid._Nprocessors; @@ -485,7 +489,8 @@ int main (int argc, char ** argv) dbytes=0; ncomm=0; - parallel_for(int dir=0;dir<8;dir++){ +#pragma omp parallel for num_threads(Grid::CartesianCommunicator::nCommThreads) + for(int dir=0;dir<8;dir++){ double tbytes; int mu =dir % 4; @@ -502,9 +507,9 @@ int main (int argc, char ** argv) int comm_proc = mpi_layout[mu]-1; Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank); } - + int tid = omp_get_thread_num(); tbytes= Grid.StencilSendToRecvFrom((void *)&xbuf[dir][0], xmit_to_rank, - (void *)&rbuf[dir][0], recv_from_rank, bytes,dir); + (void *)&rbuf[dir][0], recv_from_rank, bytes,tid); #pragma omp atomic dbytes+=tbytes; From c45f24a1b51e9b6bc8a664130a04791746c183ea Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Mon, 30 Apr 2018 21:50:00 +0100 Subject: [PATCH 093/126] Improvements for tesseract --- configure.ac | 6 +- lib/communicator/SharedMemoryMPI.cc | 229 +++++++++++++++++++++++++++- lib/stencil/Stencil.h | 2 + lib/threads/Threads.h | 2 +- 4 files changed, 230 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index aced6a9c..722b1678 100644 --- a/configure.ac +++ b/configure.ac @@ -340,7 +340,7 @@ case ${ac_PRECISION} in esac ###################### Shared memory allocation technique under MPI3 -AC_ARG_ENABLE([shm],[AC_HELP_STRING([--enable-shm=shmopen|hugetlbfs|shmnone], +AC_ARG_ENABLE([shm],[AC_HELP_STRING([--enable-shm=shmopen|shmget|hugetlbfs|shmnone], [Select SHM allocation technique])],[ac_SHM=${enable_shm}],[ac_SHM=shmopen]) case ${ac_SHM} in @@ -349,6 +349,10 @@ case ${ac_SHM} in AC_DEFINE([GRID_MPI3_SHMOPEN],[1],[GRID_MPI3_SHMOPEN] ) ;; + shmget) + AC_DEFINE([GRID_MPI3_SHMGET],[1],[GRID_MPI3_SHMGET] ) + ;; + shmnone) AC_DEFINE([GRID_MPI3_SHM_NONE],[1],[GRID_MPI3_SHM_NONE] ) ;; diff --git a/lib/communicator/SharedMemoryMPI.cc b/lib/communicator/SharedMemoryMPI.cc index d534a6d9..205d61a9 100644 --- a/lib/communicator/SharedMemoryMPI.cc +++ b/lib/communicator/SharedMemoryMPI.cc @@ -114,19 +114,169 @@ void GlobalSharedMemory::Init(Grid_MPI_Comm comm) assert(WorldNode!=-1); _ShmSetup=1; } - -void GlobalSharedMemory::OptimalCommunicator(const std::vector &processors,Grid_MPI_Comm & optimal_comm) +// Gray encode support +int BinaryToGray (int binary) { + int gray = (binary>>1)^binary; + return gray; +} +int Log2Size(int TwoToPower,int MAXLOG2) { - //////////////////////////////////////////////////////////////// - // Assert power of two shm_size. - //////////////////////////////////////////////////////////////// int log2size = -1; - for(int i=0;i<=MAXLOG2RANKSPERNODE;i++){ - if ( (0x1< &processors,Grid_MPI_Comm & optimal_comm) +{ +#undef HYPERCUBE +#ifdef HYPERCUBE + //////////////////////////////////////////////////////////////// + // Assert power of two shm_size. + //////////////////////////////////////////////////////////////// + int log2size = Log2Size(WorldShmSize,MAXLOG2RANKSPERNODE); + assert(log2size != -1); + + //////////////////////////////////////////////////////////////// + // Identify the hypercube coordinate of this node using hostname + //////////////////////////////////////////////////////////////// + // n runs 0...7 9...16 18...25 27...34 (8*4) 5 bits + // i runs 0..7 3 bits + // r runs 0..3 2 bits + // 2^10 = 1024 nodes + const int maxhdim = 10; + std::vector HyperCubeCoords(maxhdim,0); + std::vector RootHyperCubeCoords(maxhdim,0); + int R; + int I; + int N; + const int namelen = _POSIX_HOST_NAME_MAX; + char name[namelen]; + + // Parse ICE-XA hostname to get hypercube location + gethostname(name,namelen); + int nscan = sscanf(name,"r%di%dn%d",&R,&I,&N) ; + assert(nscan==3); + + int nlo = N%9; + int nhi = N/9; + uint32_t hypercoor = (R<<8)|(I<<5)|(nhi<<3)|nlo ; + uint32_t rootcoor = hypercoor; + + ////////////////////////////////////////////////////////////////// + // Print debug info + ////////////////////////////////////////////////////////////////// + for(int d=0;d>d)&0x1; + } + + std::cerr << " Hcoor (" ; + for(int d=0;d=0); + std::cerr << " WorldRank "<>d)&0x1; + } + + std::cerr << " rel Hcoor ("; + for(int d=0;d processor_coor(ndimension); + std::vector WorldDims = processors; std::vector ShmDims (ndimension,1); std::vector NodeDims (ndimension); + std::vector ShmCoor (ndimension); std::vector NodeCoor (ndimension); std::vector WorldCoor(ndimension); + std::vector HyperCoor(ndimension); + int dim = 0; + for(int l2=0;l2> bits; + } + //////////////////////////////////////////////////////////////// + // Check processor counts match + //////////////////////////////////////////////////////////////// + int Nprocessors=1; + for(int i=0;i &processors, ///////////////////////////////////////////////////////////////// int ierr= MPI_Comm_split(WorldComm,0,rank,&optimal_comm); assert(ierr==0); +#endif } +//////////////////////////////////////////////////////////////////////////////////////////// +// SHMGET +//////////////////////////////////////////////////////////////////////////////////////////// +#ifdef GRID_MPI3_SHMGET +void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) +{ + std::cout << "SharedMemoryAllocate "<< bytes<< " shmget implementation "< shmids(WorldShmSize); + + if ( WorldShmRank == 0 ) { + for(int r=0;r >& table,const La parallel_for(int i=0;i #define PARALLEL_FOR_LOOP _Pragma("omp parallel for schedule(static)") #define PARALLEL_FOR_LOOP_INTERN _Pragma("omp for schedule(static)") -#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for schedule(static) collapse(2)") +#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)") #define PARALLEL_REGION _Pragma("omp parallel") #define PARALLEL_CRITICAL _Pragma("omp critical") #else From edc28dcfbf0df697e78bb8718e3ad4980fe885ad Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Tue, 1 May 2018 14:02:31 +0100 Subject: [PATCH 094/126] Hadrons: scalar SU(N) 2-pt fix --- .../Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index abca6212..1496edf9 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -64,9 +64,9 @@ template class TTwoPoint: public Module { public: - typedef typename SImpl::Field Field; - typedef typename SImpl::ComplexField ComplexField; - typedef std::vector SlicedOp; + typedef typename SImpl::Field Field; + typedef typename SImpl::ComplexField ComplexField; + typedef std::vector SlicedOp; public: // constructor TTwoPoint(const std::string name); @@ -160,18 +160,24 @@ void TTwoPoint::execute(void) LOG(Message) << " <" << p.first << " " << p.second << ">" << std::endl; } - const unsigned int nd = env().getDim().size(); - const unsigned int nt = env().getDim().back(); - const unsigned int nop = par().op.size(); - const unsigned int nmom = mom_.size(); + const unsigned int nd = env().getNd(); + const unsigned int nt = env().getDim().back(); + const unsigned int nop = par().op.size(); + const unsigned int nmom = mom_.size(); + double partVol = 1.; std::vector dMask(nd, 1); std::set ops; std::vector result; std::map> slicedOp; FFT fft(env().getGrid()); + TComplex buf; envGetTmp(ComplexField, ftBuf); dMask[nd - 1] = 0; + for (unsigned int mu = 0; mu < nd - 1; ++mu) + { + partVol *= env().getDim()[mu]; + } for (auto &p: par().op) { ops.insert(p.first); @@ -183,7 +189,7 @@ void TTwoPoint::execute(void) slicedOp[o].resize(nmom); LOG(Message) << "Operator '" << o << "' FFT" << std::endl; - fft.FFT_dim_mask(ftBuf, op, dMask, FFT::backward); + fft.FFT_dim_mask(ftBuf, op, dMask, FFT::forward); for (unsigned int m = 0; m < nmom; ++m) { auto qt = mom_[m]; @@ -193,7 +199,8 @@ void TTwoPoint::execute(void) for (unsigned int t = 0; t < nt; ++t) { qt[nd - 1] = t; - peekSite(slicedOp[o][m][t], ftBuf, qt); + peekSite(buf, ftBuf, qt); + slicedOp[o][m][t] = TensorRemove(buf)/partVol; } } } @@ -228,7 +235,7 @@ std::vector TTwoPoint::makeTwoPoint( { for (unsigned int t = 0; t < nt; ++t) { - res[dt] += TensorRemove(trace(sink[(t+dt)%nt]*adj(source[t]))); + res[dt] += sink[(t+dt)%nt]*adj(source[t]); } res[dt] *= 1./static_cast(nt); } From a64497265d05583d1910b3c293e109c487aab2d6 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Wed, 2 May 2018 14:07:28 +0100 Subject: [PATCH 095/126] TIming --- lib/stencil/Stencil.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/stencil/Stencil.h b/lib/stencil/Stencil.h index dc64f616..a79064eb 100644 --- a/lib/stencil/Stencil.h +++ b/lib/stencil/Stencil.h @@ -507,25 +507,24 @@ class CartesianStencil { // Stencil runs along coordinate axes only; NO diagonal template void CommsMerge(decompressor decompress,std::vector &mm,std::vector &dd) { + mergetime-=usecond(); for(int i=0;i Date: Wed, 2 May 2018 14:07:41 +0100 Subject: [PATCH 096/126] shmget reintroduce --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 722b1678..819253a0 100644 --- a/configure.ac +++ b/configure.ac @@ -370,7 +370,7 @@ esac AC_ARG_ENABLE([shmpath],[AC_HELP_STRING([--enable-shmpath=path], [Select SHM mmap base path for hugetlbfs])], [ac_SHMPATH=${enable_shmpath}], - [ac_SHMPATH=/var/lib/hugetlbfs/pagesize-2MB/]) + [ac_SHMPATH=/var/lib/hugetlbfs/global/pagesize-2MB/]) AC_DEFINE_UNQUOTED([GRID_SHM_PATH],["$ac_SHMPATH"],[Path to a hugetlbfs filesystem for MMAPing]) ############### communication type selection From 12982a4455189cc568a18f1d6cffe819fc706c4e Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Wed, 2 May 2018 14:10:21 +0100 Subject: [PATCH 097/126] Hypercube optimisation --- lib/communicator/SharedMemoryMPI.cc | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/lib/communicator/SharedMemoryMPI.cc b/lib/communicator/SharedMemoryMPI.cc index 205d61a9..d55ff5df 100644 --- a/lib/communicator/SharedMemoryMPI.cc +++ b/lib/communicator/SharedMemoryMPI.cc @@ -173,15 +173,9 @@ void GlobalSharedMemory::OptimalCommunicator(const std::vector &processors, HyperCubeCoords[d] = (hypercoor>>d)&0x1; } - std::cerr << " Hcoor (" ; - for(int d=0;d &processors, hypercoor=hypercoor-rootcoor; assert(hypercoor=0); - std::cerr << " WorldRank "< &processors, HyperCubeCoords[d] = (hypercoor>>d)&0x1; } - std::cerr << " rel Hcoor ("; - for(int d=0;d &processors, int rank; Lexicographic::CoorFromIndexReversed(NodeCoor,WorldNode ,NodeDims); - std::cerr << "NodeCoor "; - for(int d=0;d Date: Wed, 2 May 2018 14:10:55 +0100 Subject: [PATCH 098/126] Revert to fast versoin --- lib/qcd/action/fermion/WilsonKernelsHand.cc | 616 +++++--------------- 1 file changed, 148 insertions(+), 468 deletions(-) diff --git a/lib/qcd/action/fermion/WilsonKernelsHand.cc b/lib/qcd/action/fermion/WilsonKernelsHand.cc index aa6b5f6b..50816495 100644 --- a/lib/qcd/action/fermion/WilsonKernelsHand.cc +++ b/lib/qcd/action/fermion/WilsonKernelsHand.cc @@ -30,181 +30,60 @@ Author: paboyle #define REGISTER -#define LOAD_CHIMU_BODY(F) \ - Chimu_00=ref(F)(0)(0); \ - Chimu_01=ref(F)(0)(1); \ - Chimu_02=ref(F)(0)(2); \ - Chimu_10=ref(F)(1)(0); \ - Chimu_11=ref(F)(1)(1); \ - Chimu_12=ref(F)(1)(2); \ - Chimu_20=ref(F)(2)(0); \ - Chimu_21=ref(F)(2)(1); \ - Chimu_22=ref(F)(2)(2); \ - Chimu_30=ref(F)(3)(0); \ - Chimu_31=ref(F)(3)(1); \ - Chimu_32=ref(F)(3)(2) +#define LOAD_CHIMU \ + {const SiteSpinor & ref (in._odata[offset]); \ + Chimu_00=ref()(0)(0);\ + Chimu_01=ref()(0)(1);\ + Chimu_02=ref()(0)(2);\ + Chimu_10=ref()(1)(0);\ + Chimu_11=ref()(1)(1);\ + Chimu_12=ref()(1)(2);\ + Chimu_20=ref()(2)(0);\ + Chimu_21=ref()(2)(1);\ + Chimu_22=ref()(2)(2);\ + Chimu_30=ref()(3)(0);\ + Chimu_31=ref()(3)(1);\ + Chimu_32=ref()(3)(2);} -#define LOAD_CHIMU(DIR,F,PERM) \ - { const SiteSpinor & ref (in._odata[offset]); LOAD_CHIMU_BODY(F); } - -#define LOAD_CHI_BODY(F) \ - Chi_00 = ref(F)(0)(0);\ - Chi_01 = ref(F)(0)(1);\ - Chi_02 = ref(F)(0)(2);\ - Chi_10 = ref(F)(1)(0);\ - Chi_11 = ref(F)(1)(1);\ - Chi_12 = ref(F)(1)(2) - -#define LOAD_CHI(DIR,F,PERM) \ - {const SiteHalfSpinor &ref(buf[offset]); LOAD_CHI_BODY(F); } - - -//G-parity implementations using in-place intrinsic ops - -//1l 1h -> 1h 1l -//0l 0h , 1h 1l -> 0l 1h 0h,1l -//0h,1l -> 1l,0h -//if( (distance == 1 && !perm_will_occur) || (distance == -1 && perm_will_occur) ) -//Pulled fermion through forwards face, GPBC on upper component -//Need 0= 0l 1h 1= 1l 0h -//else if( (distance == -1 && !perm) || (distance == 1 && perm) ) -//Pulled fermion through backwards face, GPBC on lower component -//Need 0= 1l 0h 1= 0l 1h - -//1l 1h -> 1h 1l -//0l 0h , 1h 1l -> 0l 1h 0h,1l -#define DO_TWIST_0L_1H(INTO,S,C,F, PERM, tmp1, tmp2, tmp3) \ - permute##PERM(tmp1, ref(1)(S)(C)); \ - exchange##PERM(tmp2,tmp3, ref(0)(S)(C), tmp1); \ - INTO = tmp2; - -//0l 0h -> 0h 0l -//1l 1h, 0h 0l -> 1l 0h, 1h 0l -#define DO_TWIST_1L_0H(INTO,S,C,F, PERM, tmp1, tmp2, tmp3) \ - permute##PERM(tmp1, ref(0)(S)(C)); \ - exchange##PERM(tmp2,tmp3, ref(1)(S)(C), tmp1); \ - INTO = tmp2; - - - - -#define LOAD_CHI_SETUP(DIR,F) \ - g = F; \ - direction = st._directions[DIR]; \ - distance = st._distances[DIR]; \ - sl = st._grid->_simd_layout[direction]; \ - inplace_twist = 0; \ - if(SE->_around_the_world && this->Params.twists[DIR % 4]){ \ - if(sl == 1){ \ - g = (F+1) % 2; \ - }else{ \ - inplace_twist = 1; \ - } \ - } - -#define LOAD_CHIMU_GPARITY_INPLACE_TWIST(DIR,F,PERM) \ - { const SiteSpinor &ref(in._odata[offset]); \ - LOAD_CHI_SETUP(DIR,F); \ - if(!inplace_twist){ \ - LOAD_CHIMU_BODY(g); \ - }else{ \ - if( ( F==0 && ((distance == 1 && !perm) || (distance == -1 && perm)) ) || \ - ( F==1 && ((distance == -1 && !perm) || (distance == 1 && perm)) ) ){ \ - DO_TWIST_0L_1H(Chimu_00,0,0,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chimu_01,0,1,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_0L_1H(Chimu_02,0,2,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chimu_10,1,0,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_0L_1H(Chimu_11,1,1,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chimu_12,1,2,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_0L_1H(Chimu_20,2,0,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chimu_21,2,1,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_0L_1H(Chimu_22,2,2,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chimu_30,3,0,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_0L_1H(Chimu_31,3,1,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chimu_32,3,2,F,PERM, U_11,U_20,U_21); \ - }else{ \ - DO_TWIST_1L_0H(Chimu_00,0,0,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chimu_01,0,1,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_1L_0H(Chimu_02,0,2,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chimu_10,1,0,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_1L_0H(Chimu_11,1,1,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chimu_12,1,2,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_1L_0H(Chimu_20,2,0,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chimu_21,2,1,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_1L_0H(Chimu_22,2,2,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chimu_30,3,0,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_1L_0H(Chimu_31,3,1,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chimu_32,3,2,F,PERM, U_11,U_20,U_21); \ - } \ - } \ - } - - -#define LOAD_CHI_GPARITY_INPLACE_TWIST(DIR,F,PERM) \ - { const SiteHalfSpinor &ref(buf[offset]); \ - LOAD_CHI_SETUP(DIR,F); \ - if(!inplace_twist){ \ - LOAD_CHI_BODY(g); \ - }else{ \ - if( ( F==0 && ((distance == 1 && !perm) || (distance == -1 && perm)) ) || \ - ( F==1 && ((distance == -1 && !perm) || (distance == 1 && perm)) ) ){ \ - DO_TWIST_0L_1H(Chi_00,0,0,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chi_01,0,1,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_0L_1H(Chi_02,0,2,F,PERM, UChi_00,UChi_01,UChi_02); \ - DO_TWIST_0L_1H(Chi_10,1,0,F,PERM, UChi_10,UChi_11,UChi_12); \ - DO_TWIST_0L_1H(Chi_11,1,1,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_0L_1H(Chi_12,1,2,F,PERM, U_11,U_20,U_21); \ - }else{ \ - DO_TWIST_1L_0H(Chi_00,0,0,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chi_01,0,1,F,PERM, U_11,U_20,U_21); \ - DO_TWIST_1L_0H(Chi_02,0,2,F,PERM, UChi_00,UChi_01,UChi_02); \ - DO_TWIST_1L_0H(Chi_10,1,0,F,PERM, UChi_10,UChi_11,UChi_12); \ - DO_TWIST_1L_0H(Chi_11,1,1,F,PERM, U_00,U_01,U_10); \ - DO_TWIST_1L_0H(Chi_12,1,2,F,PERM, U_11,U_20,U_21); \ - } \ - } \ - } - - -#define LOAD_CHI_GPARITY(DIR,F,PERM) LOAD_CHI_GPARITY_INPLACE_TWIST(DIR,F,PERM) -#define LOAD_CHIMU_GPARITY(DIR,F,PERM) LOAD_CHIMU_GPARITY_INPLACE_TWIST(DIR,F,PERM) +#define LOAD_CHI\ + {const SiteHalfSpinor &ref(buf[offset]); \ + Chi_00 = ref()(0)(0);\ + Chi_01 = ref()(0)(1);\ + Chi_02 = ref()(0)(2);\ + Chi_10 = ref()(1)(0);\ + Chi_11 = ref()(1)(1);\ + Chi_12 = ref()(1)(2);} // To splat or not to splat depends on the implementation -#define MULT_2SPIN_BODY \ - Impl::loadLinkElement(U_00,ref()(0,0)); \ - Impl::loadLinkElement(U_10,ref()(1,0)); \ - Impl::loadLinkElement(U_20,ref()(2,0)); \ - Impl::loadLinkElement(U_01,ref()(0,1)); \ - Impl::loadLinkElement(U_11,ref()(1,1)); \ - Impl::loadLinkElement(U_21,ref()(2,1)); \ - UChi_00 = U_00*Chi_00; \ - UChi_10 = U_00*Chi_10; \ - UChi_01 = U_10*Chi_00; \ - UChi_11 = U_10*Chi_10; \ - UChi_02 = U_20*Chi_00; \ - UChi_12 = U_20*Chi_10; \ - UChi_00+= U_01*Chi_01; \ - UChi_10+= U_01*Chi_11; \ - UChi_01+= U_11*Chi_01; \ - UChi_11+= U_11*Chi_11; \ - UChi_02+= U_21*Chi_01; \ - UChi_12+= U_21*Chi_11; \ - Impl::loadLinkElement(U_00,ref()(0,2)); \ - Impl::loadLinkElement(U_10,ref()(1,2)); \ - Impl::loadLinkElement(U_20,ref()(2,2)); \ - UChi_00+= U_00*Chi_02; \ - UChi_10+= U_00*Chi_12; \ - UChi_01+= U_10*Chi_02; \ - UChi_11+= U_10*Chi_12; \ - UChi_02+= U_20*Chi_02; \ - UChi_12+= U_20*Chi_12 - - -#define MULT_2SPIN(A,F) \ - {auto & ref(U._odata[sU](A)); MULT_2SPIN_BODY; } - -#define MULT_2SPIN_GPARITY(A,F) \ - {auto & ref(U._odata[sU](F)(A)); MULT_2SPIN_BODY; } +#define MULT_2SPIN(A)\ + {auto & ref(U._odata[sU](A)); \ + Impl::loadLinkElement(U_00,ref()(0,0)); \ + Impl::loadLinkElement(U_10,ref()(1,0)); \ + Impl::loadLinkElement(U_20,ref()(2,0)); \ + Impl::loadLinkElement(U_01,ref()(0,1)); \ + Impl::loadLinkElement(U_11,ref()(1,1)); \ + Impl::loadLinkElement(U_21,ref()(2,1)); \ + UChi_00 = U_00*Chi_00;\ + UChi_10 = U_00*Chi_10;\ + UChi_01 = U_10*Chi_00;\ + UChi_11 = U_10*Chi_10;\ + UChi_02 = U_20*Chi_00;\ + UChi_12 = U_20*Chi_10;\ + UChi_00+= U_01*Chi_01;\ + UChi_10+= U_01*Chi_11;\ + UChi_01+= U_11*Chi_01;\ + UChi_11+= U_11*Chi_11;\ + UChi_02+= U_21*Chi_01;\ + UChi_12+= U_21*Chi_11;\ + Impl::loadLinkElement(U_00,ref()(0,2)); \ + Impl::loadLinkElement(U_10,ref()(1,2)); \ + Impl::loadLinkElement(U_20,ref()(2,2)); \ + UChi_00+= U_00*Chi_02;\ + UChi_10+= U_00*Chi_12;\ + UChi_01+= U_10*Chi_02;\ + UChi_11+= U_10*Chi_12;\ + UChi_02+= U_20*Chi_02;\ + UChi_12+= U_20*Chi_12;} #define PERMUTE_DIR(dir) \ @@ -428,87 +307,84 @@ Author: paboyle result_31-= UChi_11; \ result_32-= UChi_12; -#define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ +#define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON) \ SE=st.GetEntry(ptype,DIR,ss); \ offset = SE->_offset; \ local = SE->_is_local; \ perm = SE->_permute; \ if ( local ) { \ - LOAD_CHIMU_IMPL(DIR,F,PERM); \ + LOAD_CHIMU; \ PROJ; \ if ( perm) { \ PERMUTE_DIR(PERM); \ } \ } else { \ - LOAD_CHI_IMPL(DIR,F,PERM); \ + LOAD_CHI; \ } \ - MULT_2SPIN_IMPL(DIR,F); \ + MULT_2SPIN(DIR); \ RECON; - -#define HAND_STENCIL_LEG_INT(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ +#define HAND_STENCIL_LEG_INT(PROJ,PERM,DIR,RECON) \ SE=st.GetEntry(ptype,DIR,ss); \ offset = SE->_offset; \ local = SE->_is_local; \ perm = SE->_permute; \ if ( local ) { \ - LOAD_CHIMU_IMPL(DIR,F,PERM); \ + LOAD_CHIMU; \ PROJ; \ if ( perm) { \ PERMUTE_DIR(PERM); \ } \ } else if ( st.same_node[DIR] ) { \ - LOAD_CHI_IMPL(DIR,F,PERM); \ + LOAD_CHI; \ } \ if (local || st.same_node[DIR] ) { \ - MULT_2SPIN_IMPL(DIR,F); \ + MULT_2SPIN(DIR); \ RECON; \ } -#define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ +#define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON) \ SE=st.GetEntry(ptype,DIR,ss); \ offset = SE->_offset; \ - local = SE->_is_local; \ - perm = SE->_permute; \ if((!SE->_is_local)&&(!st.same_node[DIR]) ) { \ - LOAD_CHI_IMPL(DIR,F,PERM); \ - MULT_2SPIN_IMPL(DIR,F); \ + LOAD_CHI; \ + MULT_2SPIN(DIR); \ RECON; \ nmu++; \ } -#define HAND_RESULT(ss,F) \ +#define HAND_RESULT(ss) \ { \ SiteSpinor & ref (out._odata[ss]); \ - vstream(ref(F)(0)(0),result_00); \ - vstream(ref(F)(0)(1),result_01); \ - vstream(ref(F)(0)(2),result_02); \ - vstream(ref(F)(1)(0),result_10); \ - vstream(ref(F)(1)(1),result_11); \ - vstream(ref(F)(1)(2),result_12); \ - vstream(ref(F)(2)(0),result_20); \ - vstream(ref(F)(2)(1),result_21); \ - vstream(ref(F)(2)(2),result_22); \ - vstream(ref(F)(3)(0),result_30); \ - vstream(ref(F)(3)(1),result_31); \ - vstream(ref(F)(3)(2),result_32); \ + vstream(ref()(0)(0),result_00); \ + vstream(ref()(0)(1),result_01); \ + vstream(ref()(0)(2),result_02); \ + vstream(ref()(1)(0),result_10); \ + vstream(ref()(1)(1),result_11); \ + vstream(ref()(1)(2),result_12); \ + vstream(ref()(2)(0),result_20); \ + vstream(ref()(2)(1),result_21); \ + vstream(ref()(2)(2),result_22); \ + vstream(ref()(3)(0),result_30); \ + vstream(ref()(3)(1),result_31); \ + vstream(ref()(3)(2),result_32); \ } -#define HAND_RESULT_EXT(ss,F) \ +#define HAND_RESULT_EXT(ss) \ if (nmu){ \ SiteSpinor & ref (out._odata[ss]); \ - ref(F)(0)(0)+=result_00; \ - ref(F)(0)(1)+=result_01; \ - ref(F)(0)(2)+=result_02; \ - ref(F)(1)(0)+=result_10; \ - ref(F)(1)(1)+=result_11; \ - ref(F)(1)(2)+=result_12; \ - ref(F)(2)(0)+=result_20; \ - ref(F)(2)(1)+=result_21; \ - ref(F)(2)(2)+=result_22; \ - ref(F)(3)(0)+=result_30; \ - ref(F)(3)(1)+=result_31; \ - ref(F)(3)(2)+=result_32; \ + ref()(0)(0)+=result_00; \ + ref()(0)(1)+=result_01; \ + ref()(0)(2)+=result_02; \ + ref()(1)(0)+=result_10; \ + ref()(1)(1)+=result_11; \ + ref()(1)(2)+=result_12; \ + ref()(2)(0)+=result_20; \ + ref()(2)(1)+=result_21; \ + ref()(2)(2)+=result_22; \ + ref()(3)(0)+=result_30; \ + ref()(3)(1)+=result_31; \ + ref()(3)(2)+=result_32; \ } @@ -587,18 +463,15 @@ WilsonKernels::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGauge int offset,local,perm, ptype; StencilEntry *SE; -#define HAND_DOP_SITE(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ - HAND_STENCIL_LEG(XM_PROJ,3,Xp,XM_RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_RESULT(ss,F) - - HAND_DOP_SITE(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); + HAND_STENCIL_LEG(XM_PROJ,3,Xp,XM_RECON); + HAND_STENCIL_LEG(YM_PROJ,2,Yp,YM_RECON_ACCUM); + HAND_STENCIL_LEG(ZM_PROJ,1,Zp,ZM_RECON_ACCUM); + HAND_STENCIL_LEG(TM_PROJ,0,Tp,TM_RECON_ACCUM); + HAND_STENCIL_LEG(XP_PROJ,3,Xm,XP_RECON_ACCUM); + HAND_STENCIL_LEG(YP_PROJ,2,Ym,YP_RECON_ACCUM); + HAND_STENCIL_LEG(ZP_PROJ,1,Zm,ZP_RECON_ACCUM); + HAND_STENCIL_LEG(TP_PROJ,0,Tm,TP_RECON_ACCUM); + HAND_RESULT(ss); } template @@ -612,19 +485,16 @@ void WilsonKernels::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,Doub StencilEntry *SE; int offset,local,perm, ptype; - -#define HAND_DOP_SITE_DAG(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ - HAND_STENCIL_LEG(XP_PROJ,3,Xp,XP_RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_RESULT(ss,F) - - HAND_DOP_SITE_DAG(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); + + HAND_STENCIL_LEG(XP_PROJ,3,Xp,XP_RECON); + HAND_STENCIL_LEG(YP_PROJ,2,Yp,YP_RECON_ACCUM); + HAND_STENCIL_LEG(ZP_PROJ,1,Zp,ZP_RECON_ACCUM); + HAND_STENCIL_LEG(TP_PROJ,0,Tp,TP_RECON_ACCUM); + HAND_STENCIL_LEG(XM_PROJ,3,Xm,XM_RECON_ACCUM); + HAND_STENCIL_LEG(YM_PROJ,2,Ym,YM_RECON_ACCUM); + HAND_STENCIL_LEG(ZM_PROJ,1,Zm,ZM_RECON_ACCUM); + HAND_STENCIL_LEG(TM_PROJ,0,Tm,TM_RECON_ACCUM); + HAND_RESULT(ss); } template void @@ -639,20 +509,16 @@ WilsonKernels::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGa int offset,local,perm, ptype; StencilEntry *SE; - -#define HAND_DOP_SITE_INT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ - ZERO_RESULT; \ - HAND_STENCIL_LEG_INT(XM_PROJ,3,Xp,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_RESULT(ss,F) - - HAND_DOP_SITE_INT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); + ZERO_RESULT; + HAND_STENCIL_LEG_INT(XM_PROJ,3,Xp,XM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(YM_PROJ,2,Yp,YM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(TM_PROJ,0,Tp,TM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(XP_PROJ,3,Xm,XP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(YP_PROJ,2,Ym,YP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(TP_PROJ,0,Tm,TP_RECON_ACCUM); + HAND_RESULT(ss); } template @@ -666,20 +532,16 @@ void WilsonKernels::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,D StencilEntry *SE; int offset,local,perm, ptype; - -#define HAND_DOP_SITE_DAG_INT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ - ZERO_RESULT; \ - HAND_STENCIL_LEG_INT(XP_PROJ,3,Xp,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_INT(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_RESULT(ss,F) - - HAND_DOP_SITE_DAG_INT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); + ZERO_RESULT; + HAND_STENCIL_LEG_INT(XP_PROJ,3,Xp,XP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(YP_PROJ,2,Yp,YP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(TP_PROJ,0,Tp,TP_RECON_ACCUM); + HAND_STENCIL_LEG_INT(XM_PROJ,3,Xm,XM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(YM_PROJ,2,Ym,YM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM); + HAND_STENCIL_LEG_INT(TM_PROJ,0,Tm,TM_RECON_ACCUM); + HAND_RESULT(ss); } template void @@ -695,20 +557,16 @@ WilsonKernels::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGa int offset,local,perm, ptype; StencilEntry *SE; int nmu=0; - -#define HAND_DOP_SITE_EXT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ - ZERO_RESULT; \ - HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xp,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_RESULT_EXT(ss,F) - - HAND_DOP_SITE_EXT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); + ZERO_RESULT; + HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xp,XM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(YM_PROJ,2,Yp,YM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tp,TM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xm,XP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(YP_PROJ,2,Ym,YP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tm,TP_RECON_ACCUM); + HAND_RESULT_EXT(ss); } template @@ -723,193 +581,18 @@ void WilsonKernels::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,D StencilEntry *SE; int offset,local,perm, ptype; int nmu=0; - -#define HAND_DOP_SITE_DAG_EXT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ - ZERO_RESULT; \ - HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xp,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ - HAND_RESULT_EXT(ss,F) - - HAND_DOP_SITE_DAG_EXT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); + ZERO_RESULT; + HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xp,XP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(YP_PROJ,2,Yp,YP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tp,TP_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xm,XM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(YM_PROJ,2,Ym,YM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM); + HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tm,TM_RECON_ACCUM); + HAND_RESULT_EXT(ss); } - //////////////////////////////////////////////// - // Specialise Gparity to simple implementation - //////////////////////////////////////////////// -#define HAND_SPECIALISE_EMPTY(IMPL) \ - template<> void \ - WilsonKernels::HandDhopSite(StencilImpl &st, \ - LebesgueOrder &lo, \ - DoubledGaugeField &U, \ - SiteHalfSpinor *buf, \ - int sF,int sU, \ - const FermionField &in, \ - FermionField &out){ assert(0); } \ - template<> void \ - WilsonKernels::HandDhopSiteDag(StencilImpl &st, \ - LebesgueOrder &lo, \ - DoubledGaugeField &U, \ - SiteHalfSpinor *buf, \ - int sF,int sU, \ - const FermionField &in, \ - FermionField &out){ assert(0); } \ - template<> void \ - WilsonKernels::HandDhopSiteInt(StencilImpl &st, \ - LebesgueOrder &lo, \ - DoubledGaugeField &U, \ - SiteHalfSpinor *buf, \ - int sF,int sU, \ - const FermionField &in, \ - FermionField &out){ assert(0); } \ - template<> void \ - WilsonKernels::HandDhopSiteExt(StencilImpl &st, \ - LebesgueOrder &lo, \ - DoubledGaugeField &U, \ - SiteHalfSpinor *buf, \ - int sF,int sU, \ - const FermionField &in, \ - FermionField &out){ assert(0); } \ - template<> void \ - WilsonKernels::HandDhopSiteDagInt(StencilImpl &st, \ - LebesgueOrder &lo, \ - DoubledGaugeField &U, \ - SiteHalfSpinor *buf, \ - int sF,int sU, \ - const FermionField &in, \ - FermionField &out){ assert(0); } \ - template<> void \ - WilsonKernels::HandDhopSiteDagExt(StencilImpl &st, \ - LebesgueOrder &lo, \ - DoubledGaugeField &U, \ - SiteHalfSpinor *buf, \ - int sF,int sU, \ - const FermionField &in, \ - FermionField &out){ assert(0); } \ - - - -#define HAND_SPECIALISE_GPARITY(IMPL) \ - template<> void \ - WilsonKernels::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ - int ss,int sU,const FermionField &in, FermionField &out) \ - { \ - typedef IMPL Impl; \ - typedef typename Simd::scalar_type S; \ - typedef typename Simd::vector_type V; \ - \ - HAND_DECLARATIONS(ignore); \ - \ - int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ - StencilEntry *SE; \ - HAND_DOP_SITE(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - HAND_DOP_SITE(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - } \ - \ - template<> \ - void WilsonKernels::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ - int ss,int sU,const FermionField &in, FermionField &out) \ - { \ - typedef IMPL Impl; \ - typedef typename Simd::scalar_type S; \ - typedef typename Simd::vector_type V; \ - \ - HAND_DECLARATIONS(ignore); \ - \ - StencilEntry *SE; \ - int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ - HAND_DOP_SITE_DAG(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - HAND_DOP_SITE_DAG(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - } \ - \ - template<> void \ - WilsonKernels::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ - int ss,int sU,const FermionField &in, FermionField &out) \ - { \ - typedef IMPL Impl; \ - typedef typename Simd::scalar_type S; \ - typedef typename Simd::vector_type V; \ - \ - HAND_DECLARATIONS(ignore); \ - \ - int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ - StencilEntry *SE; \ - HAND_DOP_SITE_INT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - HAND_DOP_SITE_INT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - } \ - \ - template<> \ - void WilsonKernels::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ - int ss,int sU,const FermionField &in, FermionField &out) \ - { \ - typedef IMPL Impl; \ - typedef typename Simd::scalar_type S; \ - typedef typename Simd::vector_type V; \ - \ - HAND_DECLARATIONS(ignore); \ - \ - StencilEntry *SE; \ - int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ - HAND_DOP_SITE_DAG_INT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - HAND_DOP_SITE_DAG_INT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - } \ - \ - template<> void \ - WilsonKernels::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ - int ss,int sU,const FermionField &in, FermionField &out) \ - { \ - typedef IMPL Impl; \ - typedef typename Simd::scalar_type S; \ - typedef typename Simd::vector_type V; \ - \ - HAND_DECLARATIONS(ignore); \ - \ - int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ - StencilEntry *SE; \ - int nmu=0; \ - HAND_DOP_SITE_EXT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - nmu = 0; \ - HAND_DOP_SITE_EXT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - } \ - template<> \ - void WilsonKernels::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ - int ss,int sU,const FermionField &in, FermionField &out) \ - { \ - typedef IMPL Impl; \ - typedef typename Simd::scalar_type S; \ - typedef typename Simd::vector_type V; \ - \ - HAND_DECLARATIONS(ignore); \ - \ - StencilEntry *SE; \ - int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ - int nmu=0; \ - HAND_DOP_SITE_DAG_EXT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - nmu = 0; \ - HAND_DOP_SITE_DAG_EXT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ - } - - -HAND_SPECIALISE_GPARITY(GparityWilsonImplF); -HAND_SPECIALISE_GPARITY(GparityWilsonImplD); -HAND_SPECIALISE_GPARITY(GparityWilsonImplFH); -HAND_SPECIALISE_GPARITY(GparityWilsonImplDF); - - - - - - - - - - - ////////////// Wilson ; uses this implementation ///////////////////// #define INSTANTIATE_THEM(A) \ @@ -930,8 +613,6 @@ INSTANTIATE_THEM(WilsonImplF); INSTANTIATE_THEM(WilsonImplD); INSTANTIATE_THEM(ZWilsonImplF); INSTANTIATE_THEM(ZWilsonImplD); -INSTANTIATE_THEM(GparityWilsonImplF); -INSTANTIATE_THEM(GparityWilsonImplD); INSTANTIATE_THEM(DomainWallVec5dImplF); INSTANTIATE_THEM(DomainWallVec5dImplD); INSTANTIATE_THEM(ZDomainWallVec5dImplF); @@ -940,12 +621,11 @@ INSTANTIATE_THEM(WilsonImplFH); INSTANTIATE_THEM(WilsonImplDF); INSTANTIATE_THEM(ZWilsonImplFH); INSTANTIATE_THEM(ZWilsonImplDF); -INSTANTIATE_THEM(GparityWilsonImplFH); -INSTANTIATE_THEM(GparityWilsonImplDF); INSTANTIATE_THEM(DomainWallVec5dImplFH); INSTANTIATE_THEM(DomainWallVec5dImplDF); INSTANTIATE_THEM(ZDomainWallVec5dImplFH); INSTANTIATE_THEM(ZDomainWallVec5dImplDF); INSTANTIATE_THEM(WilsonTwoIndexAntiSymmetricImplF); INSTANTIATE_THEM(WilsonTwoIndexAntiSymmetricImplD); + }} From 6f6c5c549a407441007e76a3f41c86bd0f3bf139 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Wed, 2 May 2018 14:11:23 +0100 Subject: [PATCH 099/126] Split off gparity --- .../fermion/WilsonKernelsHandGparity.cc | 878 ++++++++++++++++++ 1 file changed, 878 insertions(+) create mode 100644 lib/qcd/action/fermion/WilsonKernelsHandGparity.cc diff --git a/lib/qcd/action/fermion/WilsonKernelsHandGparity.cc b/lib/qcd/action/fermion/WilsonKernelsHandGparity.cc new file mode 100644 index 00000000..3bf2f10a --- /dev/null +++ b/lib/qcd/action/fermion/WilsonKernelsHandGparity.cc @@ -0,0 +1,878 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/qcd/action/fermion/WilsonKernelsHand.cc + + Copyright (C) 2015 + +Author: Peter Boyle +Author: paboyle + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + See the full license in the file "LICENSE" in the top level distribution directory + *************************************************************************************/ + /* END LEGAL */ +#include + +#define REGISTER + +#define LOAD_CHIMU_BODY(F) \ + Chimu_00=ref(F)(0)(0); \ + Chimu_01=ref(F)(0)(1); \ + Chimu_02=ref(F)(0)(2); \ + Chimu_10=ref(F)(1)(0); \ + Chimu_11=ref(F)(1)(1); \ + Chimu_12=ref(F)(1)(2); \ + Chimu_20=ref(F)(2)(0); \ + Chimu_21=ref(F)(2)(1); \ + Chimu_22=ref(F)(2)(2); \ + Chimu_30=ref(F)(3)(0); \ + Chimu_31=ref(F)(3)(1); \ + Chimu_32=ref(F)(3)(2) + +#define LOAD_CHIMU(DIR,F,PERM) \ + { const SiteSpinor & ref (in._odata[offset]); LOAD_CHIMU_BODY(F); } + +#define LOAD_CHI_BODY(F) \ + Chi_00 = ref(F)(0)(0);\ + Chi_01 = ref(F)(0)(1);\ + Chi_02 = ref(F)(0)(2);\ + Chi_10 = ref(F)(1)(0);\ + Chi_11 = ref(F)(1)(1);\ + Chi_12 = ref(F)(1)(2) + +#define LOAD_CHI(DIR,F,PERM) \ + {const SiteHalfSpinor &ref(buf[offset]); LOAD_CHI_BODY(F); } + + +//G-parity implementations using in-place intrinsic ops + +//1l 1h -> 1h 1l +//0l 0h , 1h 1l -> 0l 1h 0h,1l +//0h,1l -> 1l,0h +//if( (distance == 1 && !perm_will_occur) || (distance == -1 && perm_will_occur) ) +//Pulled fermion through forwards face, GPBC on upper component +//Need 0= 0l 1h 1= 1l 0h +//else if( (distance == -1 && !perm) || (distance == 1 && perm) ) +//Pulled fermion through backwards face, GPBC on lower component +//Need 0= 1l 0h 1= 0l 1h + +//1l 1h -> 1h 1l +//0l 0h , 1h 1l -> 0l 1h 0h,1l +#define DO_TWIST_0L_1H(INTO,S,C,F, PERM, tmp1, tmp2, tmp3) \ + permute##PERM(tmp1, ref(1)(S)(C)); \ + exchange##PERM(tmp2,tmp3, ref(0)(S)(C), tmp1); \ + INTO = tmp2; + +//0l 0h -> 0h 0l +//1l 1h, 0h 0l -> 1l 0h, 1h 0l +#define DO_TWIST_1L_0H(INTO,S,C,F, PERM, tmp1, tmp2, tmp3) \ + permute##PERM(tmp1, ref(0)(S)(C)); \ + exchange##PERM(tmp2,tmp3, ref(1)(S)(C), tmp1); \ + INTO = tmp2; + + + + +#define LOAD_CHI_SETUP(DIR,F) \ + g = F; \ + direction = st._directions[DIR]; \ + distance = st._distances[DIR]; \ + sl = st._grid->_simd_layout[direction]; \ + inplace_twist = 0; \ + if(SE->_around_the_world && this->Params.twists[DIR % 4]){ \ + if(sl == 1){ \ + g = (F+1) % 2; \ + }else{ \ + inplace_twist = 1; \ + } \ + } + +#define LOAD_CHIMU_GPARITY_INPLACE_TWIST(DIR,F,PERM) \ + { const SiteSpinor &ref(in._odata[offset]); \ + LOAD_CHI_SETUP(DIR,F); \ + if(!inplace_twist){ \ + LOAD_CHIMU_BODY(g); \ + }else{ \ + if( ( F==0 && ((distance == 1 && !perm) || (distance == -1 && perm)) ) || \ + ( F==1 && ((distance == -1 && !perm) || (distance == 1 && perm)) ) ){ \ + DO_TWIST_0L_1H(Chimu_00,0,0,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chimu_01,0,1,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_0L_1H(Chimu_02,0,2,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chimu_10,1,0,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_0L_1H(Chimu_11,1,1,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chimu_12,1,2,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_0L_1H(Chimu_20,2,0,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chimu_21,2,1,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_0L_1H(Chimu_22,2,2,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chimu_30,3,0,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_0L_1H(Chimu_31,3,1,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chimu_32,3,2,F,PERM, U_11,U_20,U_21); \ + }else{ \ + DO_TWIST_1L_0H(Chimu_00,0,0,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chimu_01,0,1,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_1L_0H(Chimu_02,0,2,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chimu_10,1,0,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_1L_0H(Chimu_11,1,1,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chimu_12,1,2,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_1L_0H(Chimu_20,2,0,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chimu_21,2,1,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_1L_0H(Chimu_22,2,2,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chimu_30,3,0,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_1L_0H(Chimu_31,3,1,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chimu_32,3,2,F,PERM, U_11,U_20,U_21); \ + } \ + } \ + } + + +#define LOAD_CHI_GPARITY_INPLACE_TWIST(DIR,F,PERM) \ + { const SiteHalfSpinor &ref(buf[offset]); \ + LOAD_CHI_SETUP(DIR,F); \ + if(!inplace_twist){ \ + LOAD_CHI_BODY(g); \ + }else{ \ + if( ( F==0 && ((distance == 1 && !perm) || (distance == -1 && perm)) ) || \ + ( F==1 && ((distance == -1 && !perm) || (distance == 1 && perm)) ) ){ \ + DO_TWIST_0L_1H(Chi_00,0,0,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chi_01,0,1,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_0L_1H(Chi_02,0,2,F,PERM, UChi_00,UChi_01,UChi_02); \ + DO_TWIST_0L_1H(Chi_10,1,0,F,PERM, UChi_10,UChi_11,UChi_12); \ + DO_TWIST_0L_1H(Chi_11,1,1,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_0L_1H(Chi_12,1,2,F,PERM, U_11,U_20,U_21); \ + }else{ \ + DO_TWIST_1L_0H(Chi_00,0,0,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chi_01,0,1,F,PERM, U_11,U_20,U_21); \ + DO_TWIST_1L_0H(Chi_02,0,2,F,PERM, UChi_00,UChi_01,UChi_02); \ + DO_TWIST_1L_0H(Chi_10,1,0,F,PERM, UChi_10,UChi_11,UChi_12); \ + DO_TWIST_1L_0H(Chi_11,1,1,F,PERM, U_00,U_01,U_10); \ + DO_TWIST_1L_0H(Chi_12,1,2,F,PERM, U_11,U_20,U_21); \ + } \ + } \ + } + + +#define LOAD_CHI_GPARITY(DIR,F,PERM) LOAD_CHI_GPARITY_INPLACE_TWIST(DIR,F,PERM) +#define LOAD_CHIMU_GPARITY(DIR,F,PERM) LOAD_CHIMU_GPARITY_INPLACE_TWIST(DIR,F,PERM) + +// To splat or not to splat depends on the implementation +#define MULT_2SPIN_BODY \ + Impl::loadLinkElement(U_00,ref()(0,0)); \ + Impl::loadLinkElement(U_10,ref()(1,0)); \ + Impl::loadLinkElement(U_20,ref()(2,0)); \ + Impl::loadLinkElement(U_01,ref()(0,1)); \ + Impl::loadLinkElement(U_11,ref()(1,1)); \ + Impl::loadLinkElement(U_21,ref()(2,1)); \ + UChi_00 = U_00*Chi_00; \ + UChi_10 = U_00*Chi_10; \ + UChi_01 = U_10*Chi_00; \ + UChi_11 = U_10*Chi_10; \ + UChi_02 = U_20*Chi_00; \ + UChi_12 = U_20*Chi_10; \ + UChi_00+= U_01*Chi_01; \ + UChi_10+= U_01*Chi_11; \ + UChi_01+= U_11*Chi_01; \ + UChi_11+= U_11*Chi_11; \ + UChi_02+= U_21*Chi_01; \ + UChi_12+= U_21*Chi_11; \ + Impl::loadLinkElement(U_00,ref()(0,2)); \ + Impl::loadLinkElement(U_10,ref()(1,2)); \ + Impl::loadLinkElement(U_20,ref()(2,2)); \ + UChi_00+= U_00*Chi_02; \ + UChi_10+= U_00*Chi_12; \ + UChi_01+= U_10*Chi_02; \ + UChi_11+= U_10*Chi_12; \ + UChi_02+= U_20*Chi_02; \ + UChi_12+= U_20*Chi_12 + + +#define MULT_2SPIN(A,F) \ + {auto & ref(U._odata[sU](A)); MULT_2SPIN_BODY; } + +#define MULT_2SPIN_GPARITY(A,F) \ + {auto & ref(U._odata[sU](F)(A)); MULT_2SPIN_BODY; } + + +#define PERMUTE_DIR(dir) \ + permute##dir(Chi_00,Chi_00);\ + permute##dir(Chi_01,Chi_01);\ + permute##dir(Chi_02,Chi_02);\ + permute##dir(Chi_10,Chi_10);\ + permute##dir(Chi_11,Chi_11);\ + permute##dir(Chi_12,Chi_12); + +// hspin(0)=fspin(0)+timesI(fspin(3)); +// hspin(1)=fspin(1)+timesI(fspin(2)); +#define XP_PROJ \ + Chi_00 = Chimu_00+timesI(Chimu_30);\ + Chi_01 = Chimu_01+timesI(Chimu_31);\ + Chi_02 = Chimu_02+timesI(Chimu_32);\ + Chi_10 = Chimu_10+timesI(Chimu_20);\ + Chi_11 = Chimu_11+timesI(Chimu_21);\ + Chi_12 = Chimu_12+timesI(Chimu_22); + +#define YP_PROJ \ + Chi_00 = Chimu_00-Chimu_30;\ + Chi_01 = Chimu_01-Chimu_31;\ + Chi_02 = Chimu_02-Chimu_32;\ + Chi_10 = Chimu_10+Chimu_20;\ + Chi_11 = Chimu_11+Chimu_21;\ + Chi_12 = Chimu_12+Chimu_22; + +#define ZP_PROJ \ + Chi_00 = Chimu_00+timesI(Chimu_20); \ + Chi_01 = Chimu_01+timesI(Chimu_21); \ + Chi_02 = Chimu_02+timesI(Chimu_22); \ + Chi_10 = Chimu_10-timesI(Chimu_30); \ + Chi_11 = Chimu_11-timesI(Chimu_31); \ + Chi_12 = Chimu_12-timesI(Chimu_32); + +#define TP_PROJ \ + Chi_00 = Chimu_00+Chimu_20; \ + Chi_01 = Chimu_01+Chimu_21; \ + Chi_02 = Chimu_02+Chimu_22; \ + Chi_10 = Chimu_10+Chimu_30; \ + Chi_11 = Chimu_11+Chimu_31; \ + Chi_12 = Chimu_12+Chimu_32; + + +// hspin(0)=fspin(0)-timesI(fspin(3)); +// hspin(1)=fspin(1)-timesI(fspin(2)); +#define XM_PROJ \ + Chi_00 = Chimu_00-timesI(Chimu_30);\ + Chi_01 = Chimu_01-timesI(Chimu_31);\ + Chi_02 = Chimu_02-timesI(Chimu_32);\ + Chi_10 = Chimu_10-timesI(Chimu_20);\ + Chi_11 = Chimu_11-timesI(Chimu_21);\ + Chi_12 = Chimu_12-timesI(Chimu_22); + +#define YM_PROJ \ + Chi_00 = Chimu_00+Chimu_30;\ + Chi_01 = Chimu_01+Chimu_31;\ + Chi_02 = Chimu_02+Chimu_32;\ + Chi_10 = Chimu_10-Chimu_20;\ + Chi_11 = Chimu_11-Chimu_21;\ + Chi_12 = Chimu_12-Chimu_22; + +#define ZM_PROJ \ + Chi_00 = Chimu_00-timesI(Chimu_20); \ + Chi_01 = Chimu_01-timesI(Chimu_21); \ + Chi_02 = Chimu_02-timesI(Chimu_22); \ + Chi_10 = Chimu_10+timesI(Chimu_30); \ + Chi_11 = Chimu_11+timesI(Chimu_31); \ + Chi_12 = Chimu_12+timesI(Chimu_32); + +#define TM_PROJ \ + Chi_00 = Chimu_00-Chimu_20; \ + Chi_01 = Chimu_01-Chimu_21; \ + Chi_02 = Chimu_02-Chimu_22; \ + Chi_10 = Chimu_10-Chimu_30; \ + Chi_11 = Chimu_11-Chimu_31; \ + Chi_12 = Chimu_12-Chimu_32; + +// fspin(0)=hspin(0); +// fspin(1)=hspin(1); +// fspin(2)=timesMinusI(hspin(1)); +// fspin(3)=timesMinusI(hspin(0)); +#define XP_RECON\ + result_00 = UChi_00;\ + result_01 = UChi_01;\ + result_02 = UChi_02;\ + result_10 = UChi_10;\ + result_11 = UChi_11;\ + result_12 = UChi_12;\ + result_20 = timesMinusI(UChi_10);\ + result_21 = timesMinusI(UChi_11);\ + result_22 = timesMinusI(UChi_12);\ + result_30 = timesMinusI(UChi_00);\ + result_31 = timesMinusI(UChi_01);\ + result_32 = timesMinusI(UChi_02); + +#define XP_RECON_ACCUM\ + result_00+=UChi_00;\ + result_01+=UChi_01;\ + result_02+=UChi_02;\ + result_10+=UChi_10;\ + result_11+=UChi_11;\ + result_12+=UChi_12;\ + result_20-=timesI(UChi_10);\ + result_21-=timesI(UChi_11);\ + result_22-=timesI(UChi_12);\ + result_30-=timesI(UChi_00);\ + result_31-=timesI(UChi_01);\ + result_32-=timesI(UChi_02); + +#define XM_RECON\ + result_00 = UChi_00;\ + result_01 = UChi_01;\ + result_02 = UChi_02;\ + result_10 = UChi_10;\ + result_11 = UChi_11;\ + result_12 = UChi_12;\ + result_20 = timesI(UChi_10);\ + result_21 = timesI(UChi_11);\ + result_22 = timesI(UChi_12);\ + result_30 = timesI(UChi_00);\ + result_31 = timesI(UChi_01);\ + result_32 = timesI(UChi_02); + +#define XM_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20+= timesI(UChi_10);\ + result_21+= timesI(UChi_11);\ + result_22+= timesI(UChi_12);\ + result_30+= timesI(UChi_00);\ + result_31+= timesI(UChi_01);\ + result_32+= timesI(UChi_02); + +#define YP_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20+= UChi_10;\ + result_21+= UChi_11;\ + result_22+= UChi_12;\ + result_30-= UChi_00;\ + result_31-= UChi_01;\ + result_32-= UChi_02; + +#define YM_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20-= UChi_10;\ + result_21-= UChi_11;\ + result_22-= UChi_12;\ + result_30+= UChi_00;\ + result_31+= UChi_01;\ + result_32+= UChi_02; + +#define ZP_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20-= timesI(UChi_00); \ + result_21-= timesI(UChi_01); \ + result_22-= timesI(UChi_02); \ + result_30+= timesI(UChi_10); \ + result_31+= timesI(UChi_11); \ + result_32+= timesI(UChi_12); + +#define ZM_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20+= timesI(UChi_00); \ + result_21+= timesI(UChi_01); \ + result_22+= timesI(UChi_02); \ + result_30-= timesI(UChi_10); \ + result_31-= timesI(UChi_11); \ + result_32-= timesI(UChi_12); + +#define TP_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20+= UChi_00; \ + result_21+= UChi_01; \ + result_22+= UChi_02; \ + result_30+= UChi_10; \ + result_31+= UChi_11; \ + result_32+= UChi_12; + +#define TM_RECON_ACCUM\ + result_00+= UChi_00;\ + result_01+= UChi_01;\ + result_02+= UChi_02;\ + result_10+= UChi_10;\ + result_11+= UChi_11;\ + result_12+= UChi_12;\ + result_20-= UChi_00; \ + result_21-= UChi_01; \ + result_22-= UChi_02; \ + result_30-= UChi_10; \ + result_31-= UChi_11; \ + result_32-= UChi_12; + +#define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + SE=st.GetEntry(ptype,DIR,ss); \ + offset = SE->_offset; \ + local = SE->_is_local; \ + perm = SE->_permute; \ + if ( local ) { \ + LOAD_CHIMU_IMPL(DIR,F,PERM); \ + PROJ; \ + if ( perm) { \ + PERMUTE_DIR(PERM); \ + } \ + } else { \ + LOAD_CHI_IMPL(DIR,F,PERM); \ + } \ + MULT_2SPIN_IMPL(DIR,F); \ + RECON; + + +#define HAND_STENCIL_LEG_INT(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + SE=st.GetEntry(ptype,DIR,ss); \ + offset = SE->_offset; \ + local = SE->_is_local; \ + perm = SE->_permute; \ + if ( local ) { \ + LOAD_CHIMU_IMPL(DIR,F,PERM); \ + PROJ; \ + if ( perm) { \ + PERMUTE_DIR(PERM); \ + } \ + } else if ( st.same_node[DIR] ) { \ + LOAD_CHI_IMPL(DIR,F,PERM); \ + } \ + if (local || st.same_node[DIR] ) { \ + MULT_2SPIN_IMPL(DIR,F); \ + RECON; \ + } + +#define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + SE=st.GetEntry(ptype,DIR,ss); \ + offset = SE->_offset; \ + local = SE->_is_local; \ + perm = SE->_permute; \ + if((!SE->_is_local)&&(!st.same_node[DIR]) ) { \ + LOAD_CHI_IMPL(DIR,F,PERM); \ + MULT_2SPIN_IMPL(DIR,F); \ + RECON; \ + nmu++; \ + } + +#define HAND_RESULT(ss,F) \ + { \ + SiteSpinor & ref (out._odata[ss]); \ + vstream(ref(F)(0)(0),result_00); \ + vstream(ref(F)(0)(1),result_01); \ + vstream(ref(F)(0)(2),result_02); \ + vstream(ref(F)(1)(0),result_10); \ + vstream(ref(F)(1)(1),result_11); \ + vstream(ref(F)(1)(2),result_12); \ + vstream(ref(F)(2)(0),result_20); \ + vstream(ref(F)(2)(1),result_21); \ + vstream(ref(F)(2)(2),result_22); \ + vstream(ref(F)(3)(0),result_30); \ + vstream(ref(F)(3)(1),result_31); \ + vstream(ref(F)(3)(2),result_32); \ + } + +#define HAND_RESULT_EXT(ss,F) \ + if (nmu){ \ + SiteSpinor & ref (out._odata[ss]); \ + ref(F)(0)(0)+=result_00; \ + ref(F)(0)(1)+=result_01; \ + ref(F)(0)(2)+=result_02; \ + ref(F)(1)(0)+=result_10; \ + ref(F)(1)(1)+=result_11; \ + ref(F)(1)(2)+=result_12; \ + ref(F)(2)(0)+=result_20; \ + ref(F)(2)(1)+=result_21; \ + ref(F)(2)(2)+=result_22; \ + ref(F)(3)(0)+=result_30; \ + ref(F)(3)(1)+=result_31; \ + ref(F)(3)(2)+=result_32; \ + } + + +#define HAND_DECLARATIONS(a) \ + Simd result_00; \ + Simd result_01; \ + Simd result_02; \ + Simd result_10; \ + Simd result_11; \ + Simd result_12; \ + Simd result_20; \ + Simd result_21; \ + Simd result_22; \ + Simd result_30; \ + Simd result_31; \ + Simd result_32; \ + Simd Chi_00; \ + Simd Chi_01; \ + Simd Chi_02; \ + Simd Chi_10; \ + Simd Chi_11; \ + Simd Chi_12; \ + Simd UChi_00; \ + Simd UChi_01; \ + Simd UChi_02; \ + Simd UChi_10; \ + Simd UChi_11; \ + Simd UChi_12; \ + Simd U_00; \ + Simd U_10; \ + Simd U_20; \ + Simd U_01; \ + Simd U_11; \ + Simd U_21; + +#define ZERO_RESULT \ + result_00=zero; \ + result_01=zero; \ + result_02=zero; \ + result_10=zero; \ + result_11=zero; \ + result_12=zero; \ + result_20=zero; \ + result_21=zero; \ + result_22=zero; \ + result_30=zero; \ + result_31=zero; \ + result_32=zero; + +#define Chimu_00 Chi_00 +#define Chimu_01 Chi_01 +#define Chimu_02 Chi_02 +#define Chimu_10 Chi_10 +#define Chimu_11 Chi_11 +#define Chimu_12 Chi_12 +#define Chimu_20 UChi_00 +#define Chimu_21 UChi_01 +#define Chimu_22 UChi_02 +#define Chimu_30 UChi_10 +#define Chimu_31 UChi_11 +#define Chimu_32 UChi_12 + +namespace Grid { +namespace QCD { + +template void +WilsonKernels::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, + int ss,int sU,const FermionField &in, FermionField &out) +{ +// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... + typedef typename Simd::scalar_type S; + typedef typename Simd::vector_type V; + + HAND_DECLARATIONS(ignore); + + int offset,local,perm, ptype; + StencilEntry *SE; + +#define HAND_DOP_SITE(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + HAND_STENCIL_LEG(XM_PROJ,3,Xp,XM_RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_RESULT(ss,F) + + HAND_DOP_SITE(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); +} + +template +void WilsonKernels::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, + int ss,int sU,const FermionField &in, FermionField &out) +{ + typedef typename Simd::scalar_type S; + typedef typename Simd::vector_type V; + + HAND_DECLARATIONS(ignore); + + StencilEntry *SE; + int offset,local,perm, ptype; + +#define HAND_DOP_SITE_DAG(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + HAND_STENCIL_LEG(XP_PROJ,3,Xp,XP_RECON,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_RESULT(ss,F) + + HAND_DOP_SITE_DAG(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); +} + +template void +WilsonKernels::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, + int ss,int sU,const FermionField &in, FermionField &out) +{ +// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... + typedef typename Simd::scalar_type S; + typedef typename Simd::vector_type V; + + HAND_DECLARATIONS(ignore); + + int offset,local,perm, ptype; + StencilEntry *SE; + +#define HAND_DOP_SITE_INT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + ZERO_RESULT; \ + HAND_STENCIL_LEG_INT(XM_PROJ,3,Xp,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_RESULT(ss,F) + + HAND_DOP_SITE_INT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); +} + +template +void WilsonKernels::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, + int ss,int sU,const FermionField &in, FermionField &out) +{ + typedef typename Simd::scalar_type S; + typedef typename Simd::vector_type V; + + HAND_DECLARATIONS(ignore); + + StencilEntry *SE; + int offset,local,perm, ptype; + +#define HAND_DOP_SITE_DAG_INT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + ZERO_RESULT; \ + HAND_STENCIL_LEG_INT(XP_PROJ,3,Xp,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_INT(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_RESULT(ss,F) + + HAND_DOP_SITE_DAG_INT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); +} + +template void +WilsonKernels::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, + int ss,int sU,const FermionField &in, FermionField &out) +{ +// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... + typedef typename Simd::scalar_type S; + typedef typename Simd::vector_type V; + + HAND_DECLARATIONS(ignore); + + int offset,local,perm, ptype; + StencilEntry *SE; + int nmu=0; + +#define HAND_DOP_SITE_EXT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + ZERO_RESULT; \ + HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xp,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(YM_PROJ,2,Yp,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zp,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tp,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xm,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(YP_PROJ,2,Ym,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zm,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tm,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_RESULT_EXT(ss,F) + + HAND_DOP_SITE_EXT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); +} + +template +void WilsonKernels::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, + int ss,int sU,const FermionField &in, FermionField &out) +{ + typedef typename Simd::scalar_type S; + typedef typename Simd::vector_type V; + + HAND_DECLARATIONS(ignore); + + StencilEntry *SE; + int offset,local,perm, ptype; + int nmu=0; + +#define HAND_DOP_SITE_DAG_EXT(F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL) \ + ZERO_RESULT; \ + HAND_STENCIL_LEG_EXT(XP_PROJ,3,Xp,XP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(YP_PROJ,2,Yp,YP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(ZP_PROJ,1,Zp,ZP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(TP_PROJ,0,Tp,TP_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(XM_PROJ,3,Xm,XM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(YM_PROJ,2,Ym,YM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(ZM_PROJ,1,Zm,ZM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_STENCIL_LEG_EXT(TM_PROJ,0,Tm,TM_RECON_ACCUM,F,LOAD_CHI_IMPL,LOAD_CHIMU_IMPL,MULT_2SPIN_IMPL); \ + HAND_RESULT_EXT(ss,F) + + HAND_DOP_SITE_DAG_EXT(, LOAD_CHI,LOAD_CHIMU,MULT_2SPIN); +} + +#define HAND_SPECIALISE_GPARITY(IMPL) \ + template<> void \ + WilsonKernels::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out) \ + { \ + typedef IMPL Impl; \ + typedef typename Simd::scalar_type S; \ + typedef typename Simd::vector_type V; \ + \ + HAND_DECLARATIONS(ignore); \ + \ + int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ + StencilEntry *SE; \ + HAND_DOP_SITE(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + HAND_DOP_SITE(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + } \ + \ + template<> \ + void WilsonKernels::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out) \ + { \ + typedef IMPL Impl; \ + typedef typename Simd::scalar_type S; \ + typedef typename Simd::vector_type V; \ + \ + HAND_DECLARATIONS(ignore); \ + \ + StencilEntry *SE; \ + int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ + HAND_DOP_SITE_DAG(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + HAND_DOP_SITE_DAG(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + } \ + \ + template<> void \ + WilsonKernels::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out) \ + { \ + typedef IMPL Impl; \ + typedef typename Simd::scalar_type S; \ + typedef typename Simd::vector_type V; \ + \ + HAND_DECLARATIONS(ignore); \ + \ + int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ + StencilEntry *SE; \ + HAND_DOP_SITE_INT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + HAND_DOP_SITE_INT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + } \ + \ + template<> \ + void WilsonKernels::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out) \ + { \ + typedef IMPL Impl; \ + typedef typename Simd::scalar_type S; \ + typedef typename Simd::vector_type V; \ + \ + HAND_DECLARATIONS(ignore); \ + \ + StencilEntry *SE; \ + int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ + HAND_DOP_SITE_DAG_INT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + HAND_DOP_SITE_DAG_INT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + } \ + \ + template<> void \ + WilsonKernels::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out) \ + { \ + typedef IMPL Impl; \ + typedef typename Simd::scalar_type S; \ + typedef typename Simd::vector_type V; \ + \ + HAND_DECLARATIONS(ignore); \ + \ + int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ + StencilEntry *SE; \ + int nmu=0; \ + HAND_DOP_SITE_EXT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + nmu = 0; \ + HAND_DOP_SITE_EXT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + } \ + template<> \ + void WilsonKernels::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out) \ + { \ + typedef IMPL Impl; \ + typedef typename Simd::scalar_type S; \ + typedef typename Simd::vector_type V; \ + \ + HAND_DECLARATIONS(ignore); \ + \ + StencilEntry *SE; \ + int offset,local,perm, ptype, g, direction, distance, sl, inplace_twist; \ + int nmu=0; \ + HAND_DOP_SITE_DAG_EXT(0, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + nmu = 0; \ + HAND_DOP_SITE_DAG_EXT(1, LOAD_CHI_GPARITY,LOAD_CHIMU_GPARITY,MULT_2SPIN_GPARITY); \ + } + + +HAND_SPECIALISE_GPARITY(GparityWilsonImplF); +HAND_SPECIALISE_GPARITY(GparityWilsonImplD); +HAND_SPECIALISE_GPARITY(GparityWilsonImplFH); +HAND_SPECIALISE_GPARITY(GparityWilsonImplDF); + + + + + + + + + + + +////////////// Wilson ; uses this implementation ///////////////////// + +#define INSTANTIATE_THEM(A) \ +template void WilsonKernels::HandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf,\ + int ss,int sU,const FermionField &in, FermionField &out); \ +template void WilsonKernels::HandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out);\ +template void WilsonKernels::HandDhopSiteInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf,\ + int ss,int sU,const FermionField &in, FermionField &out); \ +template void WilsonKernels::HandDhopSiteDagInt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out); \ +template void WilsonKernels::HandDhopSiteExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf,\ + int ss,int sU,const FermionField &in, FermionField &out); \ +template void WilsonKernels::HandDhopSiteDagExt(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,SiteHalfSpinor *buf, \ + int ss,int sU,const FermionField &in, FermionField &out); + +INSTANTIATE_THEM(GparityWilsonImplF); +INSTANTIATE_THEM(GparityWilsonImplD); +INSTANTIATE_THEM(GparityWilsonImplFH); +INSTANTIATE_THEM(GparityWilsonImplDF); +}} From 6e7d5e22435eadba36fd8149821bd48e6aed0fc3 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 2 May 2018 14:28:59 +0100 Subject: [PATCH 100/126] HMC: added Scidac checkpointer and support for metadata --- lib/qcd/hmc/HMCResourceManager.h | 19 ++- lib/qcd/hmc/checkpointers/BaseCheckpointer.h | 8 ++ .../hmc/checkpointers/BinaryCheckpointer.h | 3 + .../hmc/checkpointers/CheckPointerModules.h | 16 +++ lib/qcd/hmc/checkpointers/CheckPointers.h | 1 + lib/qcd/hmc/checkpointers/ILDGCheckpointer.h | 4 + lib/qcd/hmc/checkpointers/NerscCheckpointer.h | 3 + .../hmc/checkpointers/ScidacCheckpointer.h | 125 ++++++++++++++++++ tests/hmc/Test_hmc_WG_Production.cc | 11 +- 9 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 lib/qcd/hmc/checkpointers/ScidacCheckpointer.h diff --git a/lib/qcd/hmc/HMCResourceManager.h b/lib/qcd/hmc/HMCResourceManager.h index 3e20a8c1..fcfaeaed 100644 --- a/lib/qcd/hmc/HMCResourceManager.h +++ b/lib/qcd/hmc/HMCResourceManager.h @@ -48,6 +48,22 @@ with this program; if not, write to the Free Software Foundation, Inc., } \ } +#define RegisterLoadCheckPointerMetadataFunction(NAME) \ + template < class Metadata > \ + void Load##NAME##Checkpointer(const CheckpointerParameters& Params_, const Metadata& M_) { \ + if (!have_CheckPointer) { \ + std::cout << GridLogDebug << "Loading Metadata Checkpointer " << #NAME \ + << std::endl; \ + CP = std::unique_ptr( \ + new NAME##CPModule(Params_, M_)); \ + have_CheckPointer = true; \ + } else { \ + std::cout << GridLogError << "Checkpointer already loaded " \ + << std::endl; \ + exit(1); \ + } \ + } + namespace Grid { namespace QCD { @@ -77,7 +93,7 @@ class HMCResourceManager { bool have_CheckPointer; // NOTE: operator << is not overloaded for std::vector - // so thsi function is necessary + // so this function is necessary void output_vector_string(const std::vector &vs){ for (auto &i: vs) std::cout << i << " "; @@ -254,6 +270,7 @@ class HMCResourceManager { RegisterLoadCheckPointerFunction(Nersc); #ifdef HAVE_LIME RegisterLoadCheckPointerFunction(ILDG); + RegisterLoadCheckPointerMetadataFunction(Scidac); #endif //////////////////////////////////////////////////////// diff --git a/lib/qcd/hmc/checkpointers/BaseCheckpointer.h b/lib/qcd/hmc/checkpointers/BaseCheckpointer.h index 9be9efca..f4ef252b 100644 --- a/lib/qcd/hmc/checkpointers/BaseCheckpointer.h +++ b/lib/qcd/hmc/checkpointers/BaseCheckpointer.h @@ -76,6 +76,14 @@ class BaseHmcCheckpointer : public HmcObservable { } } + void check_filename(const std::string &filename){ + std::ifstream f(filename.c_str()); + if(!f.good()){ + std::cout << GridLogError << "Filename " << filename << " not found. Aborting. " << std::endl; + abort(); + }; + } + virtual void initialize(const CheckpointerParameters &Params) = 0; virtual void CheckpointRestore(int traj, typename Impl::Field &U, diff --git a/lib/qcd/hmc/checkpointers/BinaryCheckpointer.h b/lib/qcd/hmc/checkpointers/BinaryCheckpointer.h index 59d655ad..025398eb 100644 --- a/lib/qcd/hmc/checkpointers/BinaryCheckpointer.h +++ b/lib/qcd/hmc/checkpointers/BinaryCheckpointer.h @@ -93,6 +93,9 @@ class BinaryHmcCheckpointer : public BaseHmcCheckpointer { void CheckpointRestore(int traj, Field &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG) { std::string config, rng; this->build_filenames(traj, Params, config, rng); + this->check_filename(rng); + this->check_filename(config); + BinarySimpleMunger munge; diff --git a/lib/qcd/hmc/checkpointers/CheckPointerModules.h b/lib/qcd/hmc/checkpointers/CheckPointerModules.h index 5debedef..d49d6e72 100644 --- a/lib/qcd/hmc/checkpointers/CheckPointerModules.h +++ b/lib/qcd/hmc/checkpointers/CheckPointerModules.h @@ -136,6 +136,22 @@ class ILDGCPModule: public CheckPointerModule< ImplementationPolicy> { }; +template +class ScidacCPModule: public CheckPointerModule< ImplementationPolicy> { + typedef CheckPointerModule< ImplementationPolicy> CPBase; + Metadata M; + + //using CPBase::CPBase; // for constructors + + // acquire resource + virtual void initialize(){ + this->CheckPointPtr.reset(new ScidacHmcCheckpointer(this->Par_, M)); + } +public: + ScidacCPModule(typename CPBase::APar Par, Metadata M_):M(M_), CPBase(Par) {} + template + ScidacCPModule(Reader& Reader) : Parametrized(Reader){}; +}; #endif diff --git a/lib/qcd/hmc/checkpointers/CheckPointers.h b/lib/qcd/hmc/checkpointers/CheckPointers.h index 423ce45c..e7a5fa82 100644 --- a/lib/qcd/hmc/checkpointers/CheckPointers.h +++ b/lib/qcd/hmc/checkpointers/CheckPointers.h @@ -34,6 +34,7 @@ directory #include #include #include +#include //#include diff --git a/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h b/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h index 9bcc33df..f7e6b17e 100644 --- a/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h +++ b/lib/qcd/hmc/checkpointers/ILDGCheckpointer.h @@ -95,6 +95,10 @@ class ILDGHmcCheckpointer : public BaseHmcCheckpointer { GridParallelRNG &pRNG) { std::string config, rng; this->build_filenames(traj, Params, config, rng); + this->check_filename(rng); + this->check_filename(config); + + uint32_t nersc_csum,scidac_csuma,scidac_csumb; BinaryIO::readRNG(sRNG, pRNG, rng, 0,nersc_csum,scidac_csuma,scidac_csumb); diff --git a/lib/qcd/hmc/checkpointers/NerscCheckpointer.h b/lib/qcd/hmc/checkpointers/NerscCheckpointer.h index a4b1b480..d452b994 100644 --- a/lib/qcd/hmc/checkpointers/NerscCheckpointer.h +++ b/lib/qcd/hmc/checkpointers/NerscCheckpointer.h @@ -69,6 +69,9 @@ class NerscHmcCheckpointer : public BaseHmcCheckpointer { GridParallelRNG &pRNG) { std::string config, rng; this->build_filenames(traj, Params, config, rng); + this->check_filename(rng); + this->check_filename(config); + FieldMetaData header; NerscIO::readRNGState(sRNG, pRNG, header, rng); diff --git a/lib/qcd/hmc/checkpointers/ScidacCheckpointer.h b/lib/qcd/hmc/checkpointers/ScidacCheckpointer.h new file mode 100644 index 00000000..0867b882 --- /dev/null +++ b/lib/qcd/hmc/checkpointers/ScidacCheckpointer.h @@ -0,0 +1,125 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./lib/qcd/hmc/ScidacCheckpointer.h + +Copyright (C) 2018 + +Author: Guido Cossu + +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 SCIDAC_CHECKPOINTER +#define SCIDAC_CHECKPOINTER + +#ifdef HAVE_LIME + +#include +#include +#include + +namespace Grid { +namespace QCD { + +// For generic fields +template +class ScidacHmcCheckpointer : public BaseHmcCheckpointer { + private: + CheckpointerParameters Params; + Metadata MData; + + typedef typename Implementation::Field Field; + + public: + //INHERIT_GIMPL_TYPES(Implementation); + + ScidacHmcCheckpointer(const CheckpointerParameters &Params_) { initialize(Params_); } + ScidacHmcCheckpointer(const CheckpointerParameters &Params_, const Metadata& M_):MData(M_) { initialize(Params_); } + + void initialize(const CheckpointerParameters &Params_) { + Params = Params_; + + // check here that the format is valid + int ieee32big = (Params.format == std::string("IEEE32BIG")); + int ieee32 = (Params.format == std::string("IEEE32")); + int ieee64big = (Params.format == std::string("IEEE64BIG")); + int ieee64 = (Params.format == std::string("IEEE64")); + + if (!(ieee64big || ieee32 || ieee32big || ieee64)) { + std::cout << GridLogError << "Unrecognized file format " << Params.format + << std::endl; + std::cout << GridLogError + << "Allowed: IEEE32BIG | IEEE32 | IEEE64BIG | IEEE64" + << std::endl; + + exit(1); + } + } + + void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + if ((traj % Params.saveInterval) == 0) { + std::string config, rng; + this->build_filenames(traj, Params, config, rng); + GridBase *grid = U._grid; + uint32_t nersc_csum,scidac_csuma,scidac_csumb; + BinaryIO::writeRNG(sRNG, pRNG, rng, 0,nersc_csum,scidac_csuma,scidac_csumb); + ScidacWriter _ScidacWriter(grid->IsBoss()); + _ScidacWriter.open(config); + _ScidacWriter.writeScidacFieldRecord(U, MData); + _ScidacWriter.close(); + + std::cout << GridLogMessage << "Written Scidac Configuration on " << config + << " checksum " << std::hex << nersc_csum<<"/" + << scidac_csuma<<"/" << scidac_csumb + << std::dec << std::endl; + } + }; + + void CheckpointRestore(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + std::string config, rng; + this->build_filenames(traj, Params, config, rng); + this->check_filename(rng); + this->check_filename(config); + + + uint32_t nersc_csum,scidac_csuma,scidac_csumb; + BinaryIO::readRNG(sRNG, pRNG, rng, 0,nersc_csum,scidac_csuma,scidac_csumb); + + Metadata md_content; + ScidacReader _ScidacReader; + _ScidacReader.open(config); + _ScidacReader.readScidacFieldRecord(U,md_content); // format from the header + _ScidacReader.close(); + + std::cout << GridLogMessage << "Read Scidac Configuration from " << config + << " checksum " << std::hex + << nersc_csum<<"/" + << scidac_csuma<<"/" + << scidac_csumb + << std::dec << std::endl; + }; +}; +} +} + +#endif // HAVE_LIME +#endif // ILDG_CHECKPOINTER diff --git a/tests/hmc/Test_hmc_WG_Production.cc b/tests/hmc/Test_hmc_WG_Production.cc index b99446d5..7f8d8124 100644 --- a/tests/hmc/Test_hmc_WG_Production.cc +++ b/tests/hmc/Test_hmc_WG_Production.cc @@ -33,6 +33,7 @@ namespace Grid{ GRID_SERIALIZABLE_CLASS_MEMBERS(ActionParameters, double, beta) + ActionParameters() = default; template ActionParameters(Reader& Reader){ @@ -68,11 +69,15 @@ int main(int argc, char **argv) { } Serialiser Reader(TheHMC.ParameterFile); - + // Read parameters from input file + ActionParameters WilsonPar(Reader); // Checkpointer definition CheckpointerParameters CPparams(Reader); - TheHMC.Resources.LoadNerscCheckpointer(CPparams); + //TheHMC.Resources.LoadNerscCheckpointer(CPparams); + + // Store metadata in the Scidac checkpointer + TheHMC.Resources.LoadScidacCheckpointer(CPparams, WilsonPar); RNGModuleParameters RNGpar(Reader); TheHMC.Resources.SetRNGSeeds(RNGpar); @@ -91,8 +96,6 @@ int main(int argc, char **argv) { // need wrappers of the fermionic classes // that have a complex construction // standard - ActionParameters WilsonPar(Reader); - //RealD beta = 6.4 ; WilsonGaugeActionR Waction(WilsonPar.beta); ActionLevel Level1(1); From b4583267447e3f9a68c2f689b757994bfbb8f25d Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 2 May 2018 14:29:22 +0100 Subject: [PATCH 101/126] Checkpointer module update --- lib/qcd/hmc/checkpointers/CheckPointerModules.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/qcd/hmc/checkpointers/CheckPointerModules.h b/lib/qcd/hmc/checkpointers/CheckPointerModules.h index d49d6e72..f17cd2c8 100644 --- a/lib/qcd/hmc/checkpointers/CheckPointerModules.h +++ b/lib/qcd/hmc/checkpointers/CheckPointerModules.h @@ -141,8 +141,6 @@ class ScidacCPModule: public CheckPointerModule< ImplementationPolicy> { typedef CheckPointerModule< ImplementationPolicy> CPBase; Metadata M; - //using CPBase::CPBase; // for constructors - // acquire resource virtual void initialize(){ this->CheckPointPtr.reset(new ScidacHmcCheckpointer(this->Par_, M)); @@ -150,7 +148,7 @@ class ScidacCPModule: public CheckPointerModule< ImplementationPolicy> { public: ScidacCPModule(typename CPBase::APar Par, Metadata M_):M(M_), CPBase(Par) {} template - ScidacCPModule(Reader& Reader) : Parametrized(Reader){}; + ScidacCPModule(Reader& Reader) : Parametrized(Reader), M(Reader){}; }; #endif From 4d4ac2517b3348c1cf517421ad3f3038fd623bea Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 2 May 2018 14:36:32 +0100 Subject: [PATCH 102/126] Adding Scalar field theory example for Scidac format --- tests/hmc/Test_hmc_ScalarActionNxN.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/hmc/Test_hmc_ScalarActionNxN.cc b/tests/hmc/Test_hmc_ScalarActionNxN.cc index 9e40beac..33e52d82 100644 --- a/tests/hmc/Test_hmc_ScalarActionNxN.cc +++ b/tests/hmc/Test_hmc_ScalarActionNxN.cc @@ -34,6 +34,8 @@ class ScalarActionParameters : Serializable { double, lambda, double, g); + ScalarActionParameters() = default; + template ScalarActionParameters(Reader& Reader){ read(Reader, "ScalarAction", *this); @@ -124,10 +126,13 @@ int main(int argc, char **argv) { ScalarGrid.set_rb(new GridRedBlackCartesian(ScalarGrid.get_full())); TheHMC.Resources.AddGrid("scalar", ScalarGrid); std::cout << "Lattice size : " << GridDefaultLatt() << std::endl; + + ScalarActionParameters SPar(Reader); // Checkpointer definition CheckpointerParameters CPparams(Reader); - TheHMC.Resources.LoadBinaryCheckpointer(CPparams); + //TheHMC.Resources.LoadBinaryCheckpointer(CPparams); + TheHMC.Resources.LoadScidacCheckpointer(CPparams, SPar); RNGModuleParameters RNGpar(Reader); TheHMC.Resources.SetRNGSeeds(RNGpar); @@ -140,7 +145,6 @@ int main(int argc, char **argv) { // Collect actions, here use more encapsulation // Scalar action in adjoint representation - ScalarActionParameters SPar(Reader); ScalarAction Saction(SPar.mass_squared, SPar.lambda, SPar.g); // Collect actions From ba37d51ee9a6f8ec3021b55db0543002e36441f3 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 2 May 2018 15:32:06 +0100 Subject: [PATCH 103/126] Debugging the RNG IO --- lib/parallelIO/BinaryIO.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index ce84fc81..08b7b9b4 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -263,7 +263,7 @@ PARALLEL_CRITICAL GridBase *grid, std::vector &iodata, std::string file, - uint64_t offset, + uint64_t& offset, const std::string &format, int control, uint32_t &nersc_csum, uint32_t &scidac_csuma, @@ -495,6 +495,7 @@ PARALLEL_CRITICAL exit(1); #endif } + offset = fout.tellp(); fout.close(); } timer.Stop(); @@ -699,7 +700,6 @@ PARALLEL_CRITICAL IOobject(w,grid,iodata,file,offset,format,BINARYIO_WRITE|BINARYIO_LEXICOGRAPHIC, nersc_csum,scidac_csuma,scidac_csumb); - iodata.resize(1); { std::vector tmp(RngStateCount); From 8c658de17997db1f3c7990687fc61932b1d82254 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Wed, 2 May 2018 17:52:16 +0100 Subject: [PATCH 104/126] Compressor speed up (a little); streaming stores --- lib/qcd/action/fermion/WilsonCompressor.h | 32 ++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/qcd/action/fermion/WilsonCompressor.h b/lib/qcd/action/fermion/WilsonCompressor.h index b47700ac..6ec2ede9 100644 --- a/lib/qcd/action/fermion/WilsonCompressor.h +++ b/lib/qcd/action/fermion/WilsonCompressor.h @@ -69,39 +69,47 @@ class WilsonCompressorTemplate< _HCspinor, _Hspinor, _Spinor, projector, /*****************************************************/ /* Compress includes precision change if mpi data is not same */ /*****************************************************/ - inline void Compress(SiteHalfSpinor *buf,Integer o,const SiteSpinor &in) { - projector::Proj(buf[o],in,mu,dag); + inline void Compress(SiteHalfSpinor * __restrict__ buf,Integer o,const SiteSpinor &in) { + SiteHalfSpinor tmp; + projector::Proj(tmp,in,mu,dag); + vstream(buf[o],tmp); } /*****************************************************/ /* Exchange includes precision change if mpi data is not same */ /*****************************************************/ - inline void Exchange(SiteHalfSpinor *mp, - SiteHalfSpinor *vp0, - SiteHalfSpinor *vp1, + inline void Exchange(SiteHalfSpinor * __restrict__ mp, + const SiteHalfSpinor * __restrict__ vp0, + const SiteHalfSpinor * __restrict__ vp1, Integer type,Integer o){ - exchange(mp[2*o],mp[2*o+1],vp0[o],vp1[o],type); + SiteHalfSpinor tmp1; + SiteHalfSpinor tmp2; + exchange(tmp1,tmp2,vp0[o],vp1[o],type); + vstream(mp[2*o ],tmp1); + vstream(mp[2*o+1],tmp2); } /*****************************************************/ /* Have a decompression step if mpi data is not same */ /*****************************************************/ - inline void Decompress(SiteHalfSpinor *out, - SiteHalfSpinor *in, Integer o) { + inline void Decompress(SiteHalfSpinor * __restrict__ out, + SiteHalfSpinor * __restrict__ in, Integer o) { assert(0); } /*****************************************************/ /* Compress Exchange */ /*****************************************************/ - inline void CompressExchange(SiteHalfSpinor *out0, - SiteHalfSpinor *out1, - const SiteSpinor *in, + inline void CompressExchange(SiteHalfSpinor * __restrict__ out0, + SiteHalfSpinor * __restrict__ out1, + const SiteSpinor * __restrict__ in, Integer j,Integer k, Integer m,Integer type){ SiteHalfSpinor temp1, temp2,temp3,temp4; projector::Proj(temp1,in[k],mu,dag); projector::Proj(temp2,in[m],mu,dag); - exchange(out0[j],out1[j],temp1,temp2,type); + exchange(temp3,temp4,temp1,temp2,type); + vstream(out0[j],temp3); + vstream(out1[j],temp4); } /*****************************************************/ From dd6b796a01131123274517eaca8631b3b2b5c3af Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Thu, 3 May 2018 16:19:17 +0100 Subject: [PATCH 105/126] Hadrons: scalar SU(N) volume factor fix --- extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index 1496edf9..8ee80242 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -83,7 +83,8 @@ private: // make 2-pt function template std::vector makeTwoPoint(const std::vector &sink, - const std::vector &source); + const std::vector &source, + const double factor = 1.); private: std::vector> mom_; }; @@ -200,7 +201,7 @@ void TTwoPoint::execute(void) { qt[nd - 1] = t; peekSite(buf, ftBuf, qt); - slicedOp[o][m][t] = TensorRemove(buf)/partVol; + slicedOp[o][m][t] = TensorRemove(buf); } } } @@ -213,7 +214,8 @@ void TTwoPoint::execute(void) r.sink = p.first; r.source = p.second; r.mom = mom_[m]; - r.data = makeTwoPoint(slicedOp[p.first][m], slicedOp[p.second][m]); + r.data = makeTwoPoint(slicedOp[p.first][m], slicedOp[p.second][m], + 1./partVol); result.push_back(r); } saveResult(par().output, "twopt", result); @@ -224,7 +226,8 @@ template template std::vector TTwoPoint::makeTwoPoint( const std::vector &sink, - const std::vector &source) + const std::vector &source, + const double factor) { assert(sink.size() == source.size()); @@ -237,7 +240,7 @@ std::vector TTwoPoint::makeTwoPoint( { res[dt] += sink[(t+dt)%nt]*adj(source[t]); } - res[dt] *= 1./static_cast(nt); + res[dt] *= factor/static_cast(nt); } return res; From bfbf2f1fa046f95c1813c65e627dc16d5263cd6b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Thu, 3 May 2018 16:20:01 +0100 Subject: [PATCH 106/126] no threaded stencil benchmark if OpenMP is not supported --- benchmarks/Benchmark_comms.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/Benchmark_comms.cc b/benchmarks/Benchmark_comms.cc index 304a09fc..6d95bbe2 100644 --- a/benchmarks/Benchmark_comms.cc +++ b/benchmarks/Benchmark_comms.cc @@ -450,7 +450,7 @@ int main (int argc, char ** argv) } - +#ifdef GRID_OMP std::cout< Date: Fri, 4 May 2018 14:13:35 +0100 Subject: [PATCH 107/126] Update --- tests/Test_compressed_lanczos_hot_start.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Test_compressed_lanczos_hot_start.cc b/tests/Test_compressed_lanczos_hot_start.cc index 3276d0f8..293506c2 100644 --- a/tests/Test_compressed_lanczos_hot_start.cc +++ b/tests/Test_compressed_lanczos_hot_start.cc @@ -167,7 +167,7 @@ int main (int argc, char ** argv) { RealD mass = Params.mass; RealD M5 = Params.M5; std::vector blockSize = Params.blockSize; - std::vector latt({16,16,16,16}); + std::vector latt({32,32,16,16}); uint64_t vol = Ls*latt[0]*latt[1]*latt[2]*latt[3]; double mat_flop= 2.0*1320.0*vol; // Grids From 4ad0df6fde7b888cfb25e68af0a8b68aada0831f Mon Sep 17 00:00:00 2001 From: paboyle Date: Fri, 4 May 2018 17:33:23 +0100 Subject: [PATCH 108/126] Bump volume for Gerardo --- tests/Test_compressed_lanczos_hot_start.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Test_compressed_lanczos_hot_start.cc b/tests/Test_compressed_lanczos_hot_start.cc index 293506c2..65f69c54 100644 --- a/tests/Test_compressed_lanczos_hot_start.cc +++ b/tests/Test_compressed_lanczos_hot_start.cc @@ -167,7 +167,7 @@ int main (int argc, char ** argv) { RealD mass = Params.mass; RealD M5 = Params.M5; std::vector blockSize = Params.blockSize; - std::vector latt({32,32,16,16}); + std::vector latt({32,32,32,32}); uint64_t vol = Ls*latt[0]*latt[1]*latt[2]*latt[3]; double mat_flop= 2.0*1320.0*vol; // Grids From 3252059dafed52add248b03b6277270f31bd7d8e Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 17:25:36 +0100 Subject: [PATCH 109/126] Hadrons: multi-file support for eigenpacks --- extras/Hadrons/EigenPack.hpp | 246 ++++++++++++------ .../Modules/MIO/LoadCoarseEigenPack.hpp | 3 +- extras/Hadrons/Modules/MIO/LoadEigenPack.hpp | 3 +- .../Modules/MSolver/LocalCoherenceLanczos.hpp | 7 +- 4 files changed, 176 insertions(+), 83 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 976fba7b..6767e584 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -74,42 +74,47 @@ public: evec.resize(size, grid); } - virtual void read(const std::string fileStem, const int traj = -1) + virtual void read(const std::string fileStem, const bool multiFile, const int traj = -1) { - std::string evecFilename, evalFilename; - - makeFilenames(evecFilename, evalFilename, fileStem, traj); - XmlReader xmlReader(evalFilename); - LOG(Message) << "Reading " << eval.size() << " eigenvalues from '" - << evalFilename << "'" << std::endl; - Grid::read(xmlReader, "evals", eval); - basicRead(evec, evecFilename, evec.size()); + if (multiFile) + { + for(int k = 0; k < evec.size(); ++k) + { + basicReadSingle(evec[k], eval[k], evecFilename(fileStem, k, traj), k); + } + } + else + { + basicRead(evec, eval, evecFilename(fileStem, -1, traj), evec.size()); + } } - virtual void write(const std::string fileStem, const int traj = -1) + virtual void write(const std::string fileStem, const bool multiFile, const int traj = -1) { - std::string evecFilename, evalFilename; - - makeFilenames(evecFilename, evalFilename, fileStem, traj); - XmlWriter xmlWriter(evalFilename); - LOG(Message) << "Writing " << eval.size() << " eigenvalues to '" - << evalFilename << "'" << std::endl; - Grid::write(xmlWriter, "evals", eval); - basicWrite(evecFilename, evec, evec.size()); + if (multiFile) + { + for(int k = 0; k < evec.size(); ++k) + { + basicWriteSingle(evecFilename(fileStem, k, traj), evec[k], eval[k], k); + } + } + else + { + basicWrite(evecFilename(fileStem, -1, traj), evec, eval, evec.size()); + } } protected: - void makeFilenames(std::string &evecFilename, std::string &evalFilename, - const std::string stem, const int traj = -1) + std::string evecFilename(const std::string stem, const int vec, const int traj) { std::string t = (traj < 0) ? "" : ("." + std::to_string(traj)); + std::string v = (traj < 0) ? "" : (".v" + std::to_string(vec)); - evecFilename = stem + "_evec" + t + ".bin"; - evalFilename = stem + "_eval" + t + ".xml"; + return stem + "_evec" + t + v + ".bin"; } template - void basicRead(std::vector &evec, const std::string filename, - const unsigned int size) + void basicRead(std::vector &evec, std::vector &eval, + const std::string filename, const unsigned int size) { ScidacReader binReader; @@ -124,16 +129,38 @@ protected: if (vecRecord.index != k) { HADRONS_ERROR(Io, "Eigenvector " + std::to_string(k) + " has a" - + " wrong index (expected " + std::to_string(vecRecord.index) - + ") in file '" + filename + "'"); + + " wrong index (expected " + std::to_string(vecRecord.index) + + ") in file '" + filename + "'"); } + eval[k] = vecRecord.eval; } binReader.close(); } + template + void basicReadSingle(T &evec, double &eval, const std::string filename, + const unsigned int index) + { + ScidacReader binReader; + VecRecord vecRecord; + + binReader.open(filename); + binReader.skipPastObjectRecord(SCIDAC_FILE_XML); + LOG(Message) << "Reading eigenvector " << index << std::endl; + binReader.readScidacFieldRecord(evec, vecRecord); + if (vecRecord.index != index) + { + HADRONS_ERROR(Io, "Eigenvector " + std::to_string(index) + " has a" + + " wrong index (expected " + std::to_string(vecRecord.index) + + ") in file '" + filename + "'"); + } + eval = vecRecord.eval; + binReader.close(); + } + template void basicWrite(const std::string filename, std::vector &evec, - const unsigned int size) + const std::vector &eval, const unsigned int size) { ScidacWriter binWriter(evec[0]._grid->IsBoss()); XmlWriter xmlWriter("", "eigenPackPar"); @@ -153,6 +180,25 @@ protected: } binWriter.close(); } + + template + void basicWriteSingle(const std::string filename, T &evec, + const double eval, const unsigned int index) + { + ScidacWriter binWriter(evec._grid->IsBoss()); + XmlWriter xmlWriter("", "eigenPackPar"); + VecRecord vecRecord; + + xmlWriter.pushXmlString(record.operatorXml); + xmlWriter.pushXmlString(record.solverXml); + binWriter.open(filename); + binWriter.writeLimeObject(1, 1, xmlWriter, "parameters", SCIDAC_FILE_XML); + vecRecord.index = index; + vecRecord.eval = eval; + LOG(Message) << "Writing eigenvector " << index << std::endl; + binWriter.writeScidacFieldRecord(evec, vecRecord); + binWriter.close(); + } }; template @@ -181,77 +227,121 @@ public: evecCoarse.resize(sizeCoarse, gridCoarse); } - void readFine(const std::string fileStem, const int traj = -1) + void readFine(const std::string fileStem, const bool multiFile, const int traj = -1) { - std::string evecFineFilename, evalFineFilename; - std::string evecCoarseFilename, evalCoarseFilename; + // std::string evecFineFilename, evalFineFilename; + // std::string evecCoarseFilename, evalCoarseFilename; - this->makeFilenames(evecFineFilename, evalFineFilename, - fileStem + "_fine", traj); - XmlReader xmlFineReader(evalFineFilename); - LOG(Message) << "Reading " << this->eval.size() << " fine eigenvalues from '" - << evalFineFilename << "'" << std::endl; - Grid::read(xmlFineReader, "evals", this->eval); - LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '" - << evecFineFilename << "'" << std::endl; - this->basicRead(this->evec, evecFineFilename, this->evec.size()); + // this->makeFilenames(evecFineFilename, evalFineFilename, + // fileStem + "_fine", traj); + // XmlReader xmlFineReader(evalFineFilename); + // LOG(Message) << "Reading " << this->eval.size() << " fine eigenvalues from '" + // << evalFineFilename << "'" << std::endl; + // Grid::read(xmlFineReader, "evals", this->eval); + // LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '" + // << evecFineFilename << "'" << std::endl; + // this->basicRead(this->evec, evecFineFilename, this->evec.size()); + if (multiFile) + { + for(int k = 0; k < this->evec.size(); ++k) + { + this->basicReadSingle(this->evec[k], this->eval[k], this->evecFilename(fileStem + "_fine", k, traj), k); + } + } + else + { + this->basicRead(this->evec, this->eval, this->evecFilename(fileStem + "_fine", -1, traj), this->evec.size()); + } } - void readCoarse(const std::string fileStem, const int traj = -1) + void readCoarse(const std::string fileStem, const bool multiFile, const int traj = -1) { - std::string evecCoarseFilename, evalCoarseFilename; + // std::string evecCoarseFilename, evalCoarseFilename; - this->makeFilenames(evecCoarseFilename, evalCoarseFilename, - fileStem + "_coarse", traj); - XmlReader xmlCoarseReader(evalCoarseFilename); - LOG(Message) << "Reading " << evalCoarse.size() << " coarse eigenvalues from '" - << evalCoarseFilename << "'" << std::endl; - Grid::read(xmlCoarseReader, "evals", evalCoarse); - LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" - << evecCoarseFilename << "'" << std::endl; - this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); + // this->makeFilenames(evecCoarseFilename, evalCoarseFilename, + // fileStem + "_coarse", traj); + // XmlReader xmlCoarseReader(evalCoarseFilename); + // LOG(Message) << "Reading " << evalCoarse.size() << " coarse eigenvalues from '" + // << evalCoarseFilename << "'" << std::endl; + // Grid::read(xmlCoarseReader, "evals", evalCoarse); + // LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" + // << evecCoarseFilename << "'" << std::endl; + // this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); + if (multiFile) + { + for(int k = 0; k < evecCoarse.size(); ++k) + { + this->basicReadSingle(evecCoarse[k], evalCoarse[k], this->evecFilename(fileStem + "_coarse", k, traj), k); + } + } + else + { + this->basicRead(evecCoarse, evalCoarse, this->evecFilename(fileStem + "_coarse", -1, traj), evecCoarse.size()); + } } - virtual void read(const std::string fileStem, const int traj = -1) + virtual void read(const std::string fileStem, const bool multiFile, const int traj = -1) { - readFine(fileStem, traj); - readCoarse(fileStem, traj); + readFine(fileStem, multiFile, traj); + readCoarse(fileStem, multiFile, traj); } - void writeFine(const std::string fileStem, const int traj = -1) + void writeFine(const std::string fileStem, const bool multiFile, const int traj = -1) { - std::string evecFineFilename, evalFineFilename; + // std::string evecFineFilename, evalFineFilename; - this->makeFilenames(evecFineFilename, evalFineFilename, - fileStem + "_fine", traj); - XmlWriter xmlFineWriter(evalFineFilename); - LOG(Message) << "Writing " << this->eval.size() << " fine eigenvalues to '" - << evalFineFilename << "'" << std::endl; - Grid::write(xmlFineWriter, "evals", this->eval); - LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '" - << evecFineFilename << "'" << std::endl; - this->basicWrite(evecFineFilename, this->evec, this->evec.size()); + // this->makeFilenames(evecFineFilename, evalFineFilename, + // fileStem + "_fine", traj); + // XmlWriter xmlFineWriter(evalFineFilename); + // LOG(Message) << "Writing " << this->eval.size() << " fine eigenvalues to '" + // << evalFineFilename << "'" << std::endl; + // Grid::write(xmlFineWriter, "evals", this->eval); + // LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '" + // << evecFineFilename << "'" << std::endl; + // this->basicWrite(evecFineFilename, this->evec, this->evec.size()); + if (multiFile) + { + for(int k = 0; k < this->evec.size(); ++k) + { + this->basicWriteSingle(this->evecFilename(fileStem + "_fine", k, traj), this->evec[k], this->eval[k], k); + } + } + else + { + this->basicWrite(this->evecFilename(fileStem + "_fine", -1, traj), this->evec, this->eval, this->evec.size()); + } } - void writeCoarse(const std::string fileStem, const int traj = -1) + void writeCoarse(const std::string fileStem, const bool multiFile, const int traj = -1) { - std::string evecCoarseFilename, evalCoarseFilename; + // std::string evecCoarseFilename, evalCoarseFilename; - this->makeFilenames(evecCoarseFilename, evalCoarseFilename, - fileStem + "_coarse", traj); - XmlWriter xmlCoarseWriter(evalCoarseFilename); - LOG(Message) << "Writing " << evalCoarse.size() << " coarse eigenvalues to '" - << evalCoarseFilename << "'" << std::endl; - Grid::write(xmlCoarseWriter, "evals", evalCoarse); - LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" - << evecCoarseFilename << "'" << std::endl; - this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); + // this->makeFilenames(evecCoarseFilename, evalCoarseFilename, + // fileStem + "_coarse", traj); + // XmlWriter xmlCoarseWriter(evalCoarseFilename); + // LOG(Message) << "Writing " << evalCoarse.size() << " coarse eigenvalues to '" + // << evalCoarseFilename << "'" << std::endl; + // Grid::write(xmlCoarseWriter, "evals", evalCoarse); + // LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" + // << evecCoarseFilename << "'" << std::endl; + // this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); + if (multiFile) + { + for(int k = 0; k < evecCoarse.size(); ++k) + { + this->basicWriteSingle(this->evecFilename(fileStem + "_coarse", k, traj), evecCoarse[k], evalCoarse[k], k); + } + } + else + { + this->basicWrite(this->evecFilename(fileStem + "_coarse", -1, traj), evecCoarse, evalCoarse, evecCoarse.size()); + } } - virtual void write(const std::string fileStem, const int traj = -1) + virtual void write(const std::string fileStem, const bool multiFile, const int traj = -1) { - writeFine(fileStem, traj); - writeCoarse(fileStem, traj); + writeFine(fileStem, multiFile, traj); + writeCoarse(fileStem, multiFile, traj); } }; diff --git a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp index 6661f3cc..945b6751 100644 --- a/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadCoarseEigenPack.hpp @@ -45,6 +45,7 @@ class LoadCoarseEigenPackPar: Serializable public: GRID_SERIALIZABLE_CLASS_MEMBERS(LoadCoarseEigenPackPar, std::string, filestem, + bool, multiFile, unsigned int, sizeFine, unsigned int, sizeCoarse, unsigned int, Ls, @@ -120,7 +121,7 @@ void TLoadCoarseEigenPack::execute(void) auto &epack = envGetDerived(BasePack, Pack, getName()); Lattice dummy(cg); - epack.read(par().filestem, vm().getTrajectory()); + epack.read(par().filestem, par().multiFile, vm().getTrajectory()); LOG(Message) << "Block Gramm-Schmidt pass 1"<< std::endl; blockOrthogonalise(dummy, epack.evec); LOG(Message) << "Block Gramm-Schmidt pass 2"<< std::endl; diff --git a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp index a95bc51e..fcad4107 100644 --- a/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp +++ b/extras/Hadrons/Modules/MIO/LoadEigenPack.hpp @@ -45,6 +45,7 @@ class LoadEigenPackPar: Serializable public: GRID_SERIALIZABLE_CLASS_MEMBERS(LoadEigenPackPar, std::string, filestem, + bool, multiFile, unsigned int, size, unsigned int, Ls); }; @@ -111,7 +112,7 @@ void TLoadEigenPack::execute(void) { auto &epack = envGetDerived(BasePack, Pack, getName()); - epack.read(par().filestem, vm().getTrajectory()); + epack.read(par().filestem, par().multiFile, vm().getTrajectory()); epack.eval.resize(par().size); } diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index b4bad7b5..c9088cf4 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -51,7 +51,8 @@ public: ChebyParams, smoother, RealD, coarseRelaxTol, std::string, blockSize, - std::string, output); + std::string, output, + bool, multiFile); }; template @@ -156,7 +157,7 @@ void TLocalCoherenceLanczos::execute(void) solver.testFine(finePar.resid*100.0); if (!par().output.empty()) { - epack.writeFine(par().output, vm().getTrajectory()); + epack.writeFine(par().output, par().multiFile, vm().getTrajectory()); } if (par().doCoarse) { @@ -173,7 +174,7 @@ void TLocalCoherenceLanczos::execute(void) par().coarseRelaxTol); if (!par().output.empty()) { - epack.writeCoarse(par().output, vm().getTrajectory()); + epack.writeCoarse(par().output, par().multiFile, vm().getTrajectory()); } } } From 3c7a4106ed20d92f4352cdb6e3394c2a8762ba44 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 17:26:39 +0100 Subject: [PATCH 110/126] Trap for deadly empty comm thread option --- lib/util/Init.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/util/Init.cc b/lib/util/Init.cc index 45a37a02..7dc8230e 100644 --- a/lib/util/Init.cc +++ b/lib/util/Init.cc @@ -385,6 +385,7 @@ void Grid_init(int *argc,char ***argv) if( GridCmdOptionExists(*argv,*argv+*argc,"--comms-threads") ){ arg= GridCmdOptionPayload(*argv,*argv+*argc,"--comms-threads"); GridCmdOptionInt(arg,CartesianCommunicator::nCommThreads); + assert(CartesianCommunicator::nCommThreads > 0); } if( GridCmdOptionExists(*argv,*argv+*argc,"--cacheblocking") ){ arg= GridCmdOptionPayload(*argv,*argv+*argc,"--cacheblocking"); From 27a4d4c951e261de26a23449919ddc6e2ff6e50e Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 17:52:54 +0100 Subject: [PATCH 111/126] Hadrons: multi-file eigenpack in separate directory --- extras/Hadrons/EigenPack.hpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 6767e584..83dccf93 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -107,9 +107,15 @@ protected: std::string evecFilename(const std::string stem, const int vec, const int traj) { std::string t = (traj < 0) ? "" : ("." + std::to_string(traj)); - std::string v = (traj < 0) ? "" : (".v" + std::to_string(vec)); - return stem + "_evec" + t + v + ".bin"; + if (vec == -1) + { + return stem + t + ".bin"; + } + else + { + return stem + t + "/v" + std::to_string(vec) + ".bin"; + } } template @@ -163,8 +169,13 @@ protected: const std::vector &eval, const unsigned int size) { ScidacWriter binWriter(evec[0]._grid->IsBoss()); - XmlWriter xmlWriter("", "eigenPackPar"); + XmlWriter xmlWriter("", "eigenPackPar"); + std::string d = dirname(filename); + if (mkdir(d)) + { + HADRONS_ERROR(Io, "cannot create directory '" + d + "'");\ + } xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); binWriter.open(filename); @@ -188,7 +199,12 @@ protected: ScidacWriter binWriter(evec._grid->IsBoss()); XmlWriter xmlWriter("", "eigenPackPar"); VecRecord vecRecord; + std::string d = dirname(filename); + if (mkdir(d)) + { + HADRONS_ERROR(Io, "cannot create directory '" + d + "'");\ + } xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); binWriter.open(filename); From 2017e4e3b4f16dda1c3ed3735925e18f7d08d52f Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 18:12:22 +0100 Subject: [PATCH 112/126] Hadrons: more verbose directory creation error --- extras/Hadrons/EigenPack.hpp | 16 ++++++++++------ extras/Hadrons/Module.hpp | 6 ++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 83dccf93..d1f6e829 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -170,11 +170,13 @@ protected: { ScidacWriter binWriter(evec[0]._grid->IsBoss()); XmlWriter xmlWriter("", "eigenPackPar"); - std::string d = dirname(filename); + std::string d = dirname(filename); + int status = mkdir(d); - if (mkdir(d)) + if (status) { - HADRONS_ERROR(Io, "cannot create directory '" + d + "'");\ + HADRONS_ERROR(Io, "cannot create directory '" + d + + "' (status " + std::to_string(status) + ")"); } xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); @@ -199,11 +201,13 @@ protected: ScidacWriter binWriter(evec._grid->IsBoss()); XmlWriter xmlWriter("", "eigenPackPar"); VecRecord vecRecord; - std::string d = dirname(filename); + std::string d = dirname(filename); + int status = mkdir(d); - if (mkdir(d)) + if (status) { - HADRONS_ERROR(Io, "cannot create directory '" + d + "'");\ + HADRONS_ERROR(Io, "cannot create directory '" + d + + "' (status " + std::to_string(status) + ")"); } xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 7f8b7796..0fe6858d 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -123,10 +123,12 @@ MACRO_REDIRECT(__VA_ARGS__, envTmpLat5, envTmpLat4)(__VA_ARGS__) if (env().getGrid()->IsBoss())\ {\ std::string _dirname = dirname(ioStem);\ + int _status = mkdir(_dirname);\ \ - if (mkdir(_dirname))\ + if (_status)\ {\ - HADRONS_ERROR(Io, "cannot create directory '" + _dirname + "'");\ + HADRONS_ERROR(Io, "cannot create directory '" + _dirname \ + + "' (status " + std::to_string(_status) + ")");\ }\ {\ ResultWriter _writer(RESULT_FILE_NAME(ioStem));\ From c24d53bbd19d1e55370de9d6f15b7542cbe46ac8 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 7 May 2018 18:55:05 +0100 Subject: [PATCH 113/126] Further debug of RNG I/O --- lib/parallelIO/BinaryIO.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 08b7b9b4..a60fe962 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -431,14 +431,20 @@ PARALLEL_CRITICAL MPI_Abort(MPI_COMM_WORLD, 1); //assert(ierr == 0); } - std::cout << GridLogDebug << "MPI read I/O set view " << file << std::endl; + std::cout << GridLogDebug << "MPI write I/O set view " << file << std::endl; ierr = MPI_File_set_view(fh, disp, mpiObject, fileArray, "native", MPI_INFO_NULL); assert(ierr == 0); - std::cout << GridLogDebug << "MPI read I/O write all " << file << std::endl; + std::cout << GridLogDebug << "MPI write I/O write all " << file << std::endl; ierr = MPI_File_write_all(fh, &iodata[0], 1, localArray, &status); assert(ierr == 0); + MPI_Offset os; + MPI_File_get_position(fh, &os); + MPI_File_get_byte_offset(fh, os, &disp); + offset = disp; + + MPI_File_close(&fh); MPI_Type_free(&fileArray); MPI_Type_free(&localArray); @@ -448,7 +454,7 @@ PARALLEL_CRITICAL } else { std::cout << GridLogMessage << "IOobject: C++ write I/O " << file << " : " - << iodata.size() * sizeof(fobj) << " bytes" << std::endl; + << iodata.size() * sizeof(fobj) << " bytes and offset " << offset << std::endl; std::ofstream fout; fout.exceptions ( std::fstream::failbit | std::fstream::badbit ); From f362c007393f1a920e004431deb3d4f35157d805 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 19:43:40 +0100 Subject: [PATCH 114/126] Hadrons: better handling of automatic directory creation --- extras/Hadrons/EigenPack.hpp | 16 ++-------------- extras/Hadrons/Global.cc | 15 +++++++++++++++ extras/Hadrons/Global.hpp | 1 + extras/Hadrons/Module.hpp | 9 +-------- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index d1f6e829..fc68a5ed 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -170,14 +170,8 @@ protected: { ScidacWriter binWriter(evec[0]._grid->IsBoss()); XmlWriter xmlWriter("", "eigenPackPar"); - std::string d = dirname(filename); - int status = mkdir(d); - if (status) - { - HADRONS_ERROR(Io, "cannot create directory '" + d - + "' (status " + std::to_string(status) + ")"); - } + makeFileDir(filename, evec[0]._grid); xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); binWriter.open(filename); @@ -201,14 +195,8 @@ protected: ScidacWriter binWriter(evec._grid->IsBoss()); XmlWriter xmlWriter("", "eigenPackPar"); VecRecord vecRecord; - std::string d = dirname(filename); - int status = mkdir(d); - if (status) - { - HADRONS_ERROR(Io, "cannot create directory '" + d - + "' (status " + std::to_string(status) + ")"); - } + makeFileDir(filename, evec._grid); xmlWriter.pushXmlString(record.operatorXml); xmlWriter.pushXmlString(record.solverXml); binWriter.open(filename); diff --git a/extras/Hadrons/Global.cc b/extras/Hadrons/Global.cc index 82bd8eba..26b74a6f 100644 --- a/extras/Hadrons/Global.cc +++ b/extras/Hadrons/Global.cc @@ -158,3 +158,18 @@ std::string Hadrons::dirname(const std::string &s) return ""; } } + +void Hadrons::makeFileDir(const std::string filename, GridBase *g) +{ + if (g->IsBoss()) + { + std::string dir = dirname(filename); + int status = mkdir(dir); + + if (status) + { + HADRONS_ERROR(Io, "cannot create directory '" + dir + + "' ( " + std::strerror(errno) + ")"); + } + } +} diff --git a/extras/Hadrons/Global.hpp b/extras/Hadrons/Global.hpp index 433dcd21..bc0be474 100644 --- a/extras/Hadrons/Global.hpp +++ b/extras/Hadrons/Global.hpp @@ -192,6 +192,7 @@ name + "." + std::to_string(vm().getTrajectory()) + "." + resultFileExt int mkdir(const std::string dirName); std::string basename(const std::string &s); std::string dirname(const std::string &s); +void makeFileDir(const std::string filename, GridBase *g); // default Schur convention #ifndef HADRONS_DEFAULT_SCHUR diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index 0fe6858d..dd038a21 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -122,14 +122,7 @@ MACRO_REDIRECT(__VA_ARGS__, envTmpLat5, envTmpLat4)(__VA_ARGS__) #define saveResult(ioStem, name, result)\ if (env().getGrid()->IsBoss())\ {\ - std::string _dirname = dirname(ioStem);\ - int _status = mkdir(_dirname);\ - \ - if (_status)\ - {\ - HADRONS_ERROR(Io, "cannot create directory '" + _dirname \ - + "' (status " + std::to_string(_status) + ")");\ - }\ + makeFileDir(ioStem, env().getGrid());\ {\ ResultWriter _writer(RESULT_FILE_NAME(ioStem));\ write(_writer, name, result);\ From 25828746f377b528198efd2ae03c61f25c6e7e20 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 21:04:31 +0100 Subject: [PATCH 115/126] XML precision scientific with 16 digits by default --- lib/serialisation/XmlIO.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/serialisation/XmlIO.h b/lib/serialisation/XmlIO.h index eaa8174b..792505d4 100644 --- a/lib/serialisation/XmlIO.h +++ b/lib/serialisation/XmlIO.h @@ -103,7 +103,8 @@ namespace Grid { std::ostringstream os; - os << std::boolalpha << x; + os.precision(16); + os << std::scientific << std::boolalpha << x; pugi::xml_node leaf = node_.append_child(s.c_str()); leaf.append_child(pugi::node_pcdata).set_value(os.str().c_str()); } From 54d789204fec8478eedd936f9a6d10e4ce5d13dd Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 21:17:46 +0100 Subject: [PATCH 116/126] more general implementation of the precision interface for serialisers --- lib/serialisation/BaseIO.h | 32 +++++++++++++++++++++++++++++++- lib/serialisation/XmlIO.h | 11 +++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/serialisation/BaseIO.h b/lib/serialisation/BaseIO.h index bc178e0d..dd15e7da 100644 --- a/lib/serialisation/BaseIO.h +++ b/lib/serialisation/BaseIO.h @@ -60,8 +60,14 @@ namespace Grid { void write(const std::string &s, const iVector &output); template void write(const std::string &s, const iMatrix &output); + void scientificFormat(const bool set); + bool isScientific(void); + void setPrecision(const unsigned int prec); + unsigned int getPrecision(void); private: - T *upcast; + T *upcast; + bool scientific_{false}; + unsigned int prec_{0}; }; // Static abstract reader @@ -155,6 +161,30 @@ namespace Grid { { upcast->writeDefault(s, tensorToVec(output)); } + + template + void Writer::scientificFormat(const bool set) + { + scientific_ = set; + } + + template + bool Writer::isScientific(void) + { + return scientific_; + } + + template + void Writer::setPrecision(const unsigned int prec) + { + prec_ = prec; + } + + template + unsigned int Writer::getPrecision(void) + { + return prec_; + } // Reader template implementation template diff --git a/lib/serialisation/XmlIO.h b/lib/serialisation/XmlIO.h index 792505d4..17ccb32e 100644 --- a/lib/serialisation/XmlIO.h +++ b/lib/serialisation/XmlIO.h @@ -103,8 +103,15 @@ namespace Grid { std::ostringstream os; - os.precision(16); - os << std::scientific << std::boolalpha << x; + if (getPrecision()) + { + os.precision(getPrecision()); + } + if (isScientific()) + { + os << std::scientific; + } + os << std::boolalpha << x; pugi::xml_node leaf = node_.append_child(s.c_str()); leaf.append_child(pugi::node_pcdata).set_value(os.str().c_str()); } From 899f961d0d6d53b9e441d296f26c2e1603c023cb Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 21:37:03 +0100 Subject: [PATCH 117/126] Hadrons: eigenvalue metadata saved with 16 significant digits --- extras/Hadrons/EigenPack.hpp | 47 +----------------------------------- extras/Hadrons/Global.hpp | 4 +++ lib/parallelIO/IldgIO.h | 12 ++++++--- 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index fc68a5ed..92901138 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -204,7 +204,7 @@ protected: vecRecord.index = index; vecRecord.eval = eval; LOG(Message) << "Writing eigenvector " << index << std::endl; - binWriter.writeScidacFieldRecord(evec, vecRecord); + binWriter.writeScidacFieldRecord(evec, vecRecord, DEFAULT_ASCII_PREC); binWriter.close(); } }; @@ -237,18 +237,6 @@ public: void readFine(const std::string fileStem, const bool multiFile, const int traj = -1) { - // std::string evecFineFilename, evalFineFilename; - // std::string evecCoarseFilename, evalCoarseFilename; - - // this->makeFilenames(evecFineFilename, evalFineFilename, - // fileStem + "_fine", traj); - // XmlReader xmlFineReader(evalFineFilename); - // LOG(Message) << "Reading " << this->eval.size() << " fine eigenvalues from '" - // << evalFineFilename << "'" << std::endl; - // Grid::read(xmlFineReader, "evals", this->eval); - // LOG(Message) << "Reading " << this->evec.size() << " fine eigenvectors from '" - // << evecFineFilename << "'" << std::endl; - // this->basicRead(this->evec, evecFineFilename, this->evec.size()); if (multiFile) { for(int k = 0; k < this->evec.size(); ++k) @@ -264,17 +252,6 @@ public: void readCoarse(const std::string fileStem, const bool multiFile, const int traj = -1) { - // std::string evecCoarseFilename, evalCoarseFilename; - - // this->makeFilenames(evecCoarseFilename, evalCoarseFilename, - // fileStem + "_coarse", traj); - // XmlReader xmlCoarseReader(evalCoarseFilename); - // LOG(Message) << "Reading " << evalCoarse.size() << " coarse eigenvalues from '" - // << evalCoarseFilename << "'" << std::endl; - // Grid::read(xmlCoarseReader, "evals", evalCoarse); - // LOG(Message) << "Reading " << evecCoarse.size() << " coarse eigenvectors from '" - // << evecCoarseFilename << "'" << std::endl; - // this->basicRead(evecCoarse, evecCoarseFilename, evecCoarse.size()); if (multiFile) { for(int k = 0; k < evecCoarse.size(); ++k) @@ -296,17 +273,6 @@ public: void writeFine(const std::string fileStem, const bool multiFile, const int traj = -1) { - // std::string evecFineFilename, evalFineFilename; - - // this->makeFilenames(evecFineFilename, evalFineFilename, - // fileStem + "_fine", traj); - // XmlWriter xmlFineWriter(evalFineFilename); - // LOG(Message) << "Writing " << this->eval.size() << " fine eigenvalues to '" - // << evalFineFilename << "'" << std::endl; - // Grid::write(xmlFineWriter, "evals", this->eval); - // LOG(Message) << "Writing " << this->evec.size() << " fine eigenvectors to '" - // << evecFineFilename << "'" << std::endl; - // this->basicWrite(evecFineFilename, this->evec, this->evec.size()); if (multiFile) { for(int k = 0; k < this->evec.size(); ++k) @@ -322,17 +288,6 @@ public: void writeCoarse(const std::string fileStem, const bool multiFile, const int traj = -1) { - // std::string evecCoarseFilename, evalCoarseFilename; - - // this->makeFilenames(evecCoarseFilename, evalCoarseFilename, - // fileStem + "_coarse", traj); - // XmlWriter xmlCoarseWriter(evalCoarseFilename); - // LOG(Message) << "Writing " << evalCoarse.size() << " coarse eigenvalues to '" - // << evalCoarseFilename << "'" << std::endl; - // Grid::write(xmlCoarseWriter, "evals", evalCoarse); - // LOG(Message) << "Writing " << evecCoarse.size() << " coarse eigenvectors to '" - // << evecCoarseFilename << "'" << std::endl; - // this->basicWrite(evecCoarseFilename, evecCoarse, evecCoarse.size()); if (multiFile) { for(int k = 0; k < evecCoarse.size(); ++k) diff --git a/extras/Hadrons/Global.hpp b/extras/Hadrons/Global.hpp index bc0be474..72fbdf80 100644 --- a/extras/Hadrons/Global.hpp +++ b/extras/Hadrons/Global.hpp @@ -39,6 +39,10 @@ See the full license in the file "LICENSE" in the top level distribution directo #define SITE_SIZE_TYPE size_t #endif +#ifndef DEFAULT_ASCII_PREC +#define DEFAULT_ASCII_PREC 16 +#endif + #define BEGIN_HADRONS_NAMESPACE \ namespace Grid {\ using namespace QCD;\ diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index 3eb55d7d..0bfa7b9e 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -340,10 +340,15 @@ class GridLimeWriter : public BinaryIO } template - void writeLimeObject(int MB,int ME,serialisable_object &object,std::string object_name,std::string record_name) + void writeLimeObject(int MB,int ME,serialisable_object &object,std::string object_name,std::string record_name, const unsigned int scientificPrec = 0) { XmlWriter WR("",""); + if (scientificPrec) + { + WR.scientificFormat(true); + WR.setPrecision(scientificPrec); + } write(WR,object_name,object); writeLimeObject(MB, ME, WR, object_name, record_name); } @@ -453,7 +458,8 @@ class ScidacWriter : public GridLimeWriter { // Write generic lattice field in scidac format //////////////////////////////////////////////// template - void writeScidacFieldRecord(Lattice &field,userRecord _userRecord) + void writeScidacFieldRecord(Lattice &field,userRecord _userRecord, + const unsigned int recordScientificPrec = 0) { GridBase * grid = field._grid; @@ -471,7 +477,7 @@ class ScidacWriter : public GridLimeWriter { ////////////////////////////////////////////// if ( this->boss_node ) { writeLimeObject(1,0,header ,std::string("FieldMetaData"),std::string(GRID_FORMAT)); // Open message - writeLimeObject(0,0,_userRecord,_userRecord.SerialisableClassName(),std::string(SCIDAC_RECORD_XML)); + writeLimeObject(0,0,_userRecord,_userRecord.SerialisableClassName(),std::string(SCIDAC_RECORD_XML), recordScientificPrec); writeLimeObject(0,0,_scidacRecord,_scidacRecord.SerialisableClassName(),std::string(SCIDAC_PRIVATE_RECORD_XML)); } // Collective call From 9ad580d82f2d479d0020bfde8c87f5209dea1b60 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 7 May 2018 21:38:15 +0100 Subject: [PATCH 118/126] Hadrons: format fix --- extras/Hadrons/EigenPack.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/EigenPack.hpp b/extras/Hadrons/EigenPack.hpp index 92901138..4169cba1 100644 --- a/extras/Hadrons/EigenPack.hpp +++ b/extras/Hadrons/EigenPack.hpp @@ -183,7 +183,7 @@ protected: vecRecord.index = k; vecRecord.eval = eval[k]; LOG(Message) << "Writing eigenvector " << k << std::endl; - binWriter.writeScidacFieldRecord(evec[k], vecRecord); + binWriter.writeScidacFieldRecord(evec[k], vecRecord, DEFAULT_ASCII_PREC); } binWriter.close(); } From 93771f30998d8876f786ee8fd9a2db1d77307f63 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Thu, 10 May 2018 22:29:48 +0100 Subject: [PATCH 119/126] Hadrons: scalar SU(N) stochastic free field --- extras/Hadrons/Modules.hpp | 31 +--- .../Modules/MScalarSUN/StochFreeField.cc | 11 ++ .../Modules/MScalarSUN/StochFreeField.hpp | 136 ++++++++++++++++++ extras/Hadrons/modules.inc | 2 + 4 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 extras/Hadrons/Modules/MScalarSUN/StochFreeField.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp diff --git a/extras/Hadrons/Modules.hpp b/extras/Hadrons/Modules.hpp index fc536393..1a18eb3a 100644 --- a/extras/Hadrons/Modules.hpp +++ b/extras/Hadrons/Modules.hpp @@ -1,33 +1,3 @@ -/************************************************************************************* - -Grid physics library, www.github.com/paboyle/Grid - -Source file: extras/Hadrons/Modules.hpp - -Copyright (C) 2015-2018 - -Author: Antonin Portelli -Author: Guido Cossu -Author: Lanny91 -Author: pretidav - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -See the full license in the file "LICENSE" in the top level distribution directory -*************************************************************************************/ -/* END LEGAL */ #include #include #include @@ -61,6 +31,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include #include +#include #include #include #include diff --git a/extras/Hadrons/Modules/MScalarSUN/StochFreeField.cc b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.cc new file mode 100644 index 00000000..0be90022 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.cc @@ -0,0 +1,11 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TStochFreeField>; +template class Grid::Hadrons::MScalarSUN::TStochFreeField>; +template class Grid::Hadrons::MScalarSUN::TStochFreeField>; +template class Grid::Hadrons::MScalarSUN::TStochFreeField>; +template class Grid::Hadrons::MScalarSUN::TStochFreeField>; diff --git a/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp new file mode 100644 index 00000000..0dcd0177 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp @@ -0,0 +1,136 @@ +#ifndef Hadrons_MScalarSUN_StochFreeField_hpp_ +#define Hadrons_MScalarSUN_StochFreeField_hpp_ + +#include +#include +#include + +BEGIN_HADRONS_NAMESPACE + +/****************************************************************************** + * stochastic free SU(N) scalar field * + ******************************************************************************/ +BEGIN_MODULE_NAMESPACE(MScalarSUN) + +class StochFreeFieldPar: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(StochFreeFieldPar, + double, m2, + double, g); +}; + +template +class TStochFreeField: public Module +{ +public: + typedef typename SImpl::Field Field; + typedef typename SImpl::ComplexField ComplexField; + typedef typename SImpl::Group Group; + typedef typename Group::LatticeAlgebraVector AlgebraField; +public: + // constructor + TStochFreeField(const std::string name); + // destructor + virtual ~TStochFreeField(void) {}; + // dependency relation + virtual std::vector getInput(void); + virtual std::vector getOutput(void); + // setup + virtual void setup(void); + // execution + virtual void execute(void); +private: + bool create_weight; +}; + +MODULE_REGISTER_TMP(StochFreeFieldSU2, TStochFreeField>, MScalarSUN); +MODULE_REGISTER_TMP(StochFreeFieldSU3, TStochFreeField>, MScalarSUN); +MODULE_REGISTER_TMP(StochFreeFieldSU4, TStochFreeField>, MScalarSUN); +MODULE_REGISTER_TMP(StochFreeFieldSU5, TStochFreeField>, MScalarSUN); +MODULE_REGISTER_TMP(StochFreeFieldSU6, TStochFreeField>, MScalarSUN); + +/****************************************************************************** + * TStochFreeField implementation * + ******************************************************************************/ +// constructor ///////////////////////////////////////////////////////////////// +template +TStochFreeField::TStochFreeField(const std::string name) +: Module(name) +{} + +// dependencies/products /////////////////////////////////////////////////////// +template +std::vector TStochFreeField::getInput(void) +{ + std::vector in; + + return in; +} + +template +std::vector TStochFreeField::getOutput(void) +{ + std::vector out = {getName()}; + + return out; +} + +// setup /////////////////////////////////////////////////////////////////////// +template +void TStochFreeField::setup(void) +{ + create_weight = false; + if (!env().hasCreatedObject("_" + getName() + "_weight")) + { + envCacheLat(ComplexField, "_" + getName() + "_weight"); + create_weight = true; + } + envTmpLat(Field, "phift"); + envCreateLat(Field, getName()); +} + +// execution /////////////////////////////////////////////////////////////////// +template +void TStochFreeField::execute(void) +{ + LOG(Message) << "Generating stochastic scalar field" << std::endl; + + const unsigned int N = Group::Dimension; + const unsigned int Nadj = Group::AdjointDimension; + auto &phi = envGet(Field, getName()); + auto &w = envGet(ComplexField, "_" + getName() + "_weight"); + auto &rng = *env().get4dRng(); + double trphi2; + FFT fft(env().getGrid()); + Integer vol; + + vol = 1; + for(int d = 0; d < env().getNd(); d++) + { + vol = vol*env().getDim(d); + } + if (create_weight) + { + LOG(Message) << "Caching momentum-space scalar action" << std::endl; + + SImpl::MomentumSpacePropagator(w, sqrt(par().m2)); + w *= par().g/N; + w = sqrt(vol*real(w)); + } + LOG(Message) << "Generating random momentum-space field" << std::endl; + envGetTmp(Field, phift); + Group::GaussianFundamentalLieAlgebraMatrix(rng, phift); + phift *= w; + LOG(Message) << "Field Fourier transform" << std::endl; + fft.FFT_all_dim(phi, phift, FFT::backward); + phi = (1./sqrt(2.))*(phi - adj(phi)); + trphi2 = -TensorRemove(sum(trace(phi*phi))).real()/vol; + LOG(Message) << "tr(phi^2)= " << trphi2 << std::endl; +} + +END_MODULE_NAMESPACE + +END_HADRONS_NAMESPACE + +#endif // Hadrons_MScalarSUN_StochFreeField_hpp_ diff --git a/extras/Hadrons/modules.inc b/extras/Hadrons/modules.inc index ad3a8727..c2e84086 100644 --- a/extras/Hadrons/modules.inc +++ b/extras/Hadrons/modules.inc @@ -37,6 +37,7 @@ modules_cc =\ Modules/MScalarSUN/EMT.cc \ Modules/MScalarSUN/ShiftProbe.cc \ Modules/MScalarSUN/TransProj.cc \ + Modules/MScalarSUN/StochFreeField.cc \ Modules/MScalarSUN/TwoPoint.cc \ Modules/MScalarSUN/Div.cc \ Modules/MIO/LoadEigenPack.cc \ @@ -78,6 +79,7 @@ modules_hpp =\ Modules/MAction/Wilson.hpp \ Modules/MAction/WilsonClover.hpp \ Modules/MAction/ZMobiusDWF.hpp \ + Modules/MScalarSUN/StochFreeField.hpp \ Modules/MScalarSUN/ShiftProbe.hpp \ Modules/MScalarSUN/Div.hpp \ Modules/MScalarSUN/TrMag.hpp \ From f871fb0c6dbd46dcc7ebb296bfd6297a5178b440 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 11 May 2018 18:06:28 +0100 Subject: [PATCH 120/126] check file is opened correctly in the Lime reader --- lib/parallelIO/IldgIO.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index 90c05546..33af6c3d 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -182,6 +182,11 @@ class GridLimeReader : public BinaryIO { { filename= _filename; File = fopen(filename.c_str(), "r"); + if (File == nullptr) + { + std::cerr << "cannot open file '" << filename << "'" << std::endl; + abort(); + } LimeR = limeCreateReader(File); } ///////////////////////////////////////////// From 5e3be47117534384cffbc4e8461f4ef176c6a42e Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 14 May 2018 18:58:39 +0100 Subject: [PATCH 121/126] Hadrons: scalar SU(N) various fixes --- extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp | 10 +++++----- extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp index cd7c15eb..edd38e42 100644 --- a/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/ShiftProbe.hpp @@ -40,7 +40,7 @@ BEGIN_HADRONS_NAMESPACE ******************************************************************************/ BEGIN_MODULE_NAMESPACE(MScalarSUN) -typedef std::pair ShiftPair; +typedef std::pair ShiftPair; class ShiftProbePar: Serializable { @@ -127,7 +127,7 @@ void TShiftProbe::execute(void) << std::endl; std::vector shift; - unsigned int sign; + double sign; auto &phi = envGet(Field, par().field); auto &probe = envGet(ComplexField, getName()); @@ -136,7 +136,7 @@ void TShiftProbe::execute(void) { HADRONS_ERROR(Size, "the number of shifts is odd"); } - sign = (shift.size() % 4 == 0) ? 1 : -1; + sign = (shift.size() % 4 == 0) ? 1. : -1.; for (auto &s: shift) { if (s.first >= env().getNd()) @@ -147,7 +147,7 @@ void TShiftProbe::execute(void) } } envGetTmp(Field, acc); - acc = 1.; + acc = 1.; for (unsigned int i = 0; i < shift.size(); ++i) { if (shift[i].second == 0) @@ -159,7 +159,7 @@ void TShiftProbe::execute(void) acc *= Cshift(phi, shift[i].first, shift[i].second); } } - probe = real(sign*trace(acc)); + probe = sign*trace(acc); if (!par().output.empty()) { ShiftProbeResult r; diff --git a/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp index 0dcd0177..6800de53 100644 --- a/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp @@ -116,7 +116,7 @@ void TStochFreeField::execute(void) SImpl::MomentumSpacePropagator(w, sqrt(par().m2)); w *= par().g/N; - w = sqrt(vol*real(w)); + w = sqrt(vol)*sqrt(w); } LOG(Message) << "Generating random momentum-space field" << std::endl; envGetTmp(Field, phift); From 9d835afa351e0a99601dc955be808b116765a8d0 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 14 May 2018 19:05:54 +0100 Subject: [PATCH 122/126] Attempt at solving the FP exception in the QED code --- lib/qcd/action/gauge/Photon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/qcd/action/gauge/Photon.h b/lib/qcd/action/gauge/Photon.h index 7e21a1de..8a6eff79 100644 --- a/lib/qcd/action/gauge/Photon.h +++ b/lib/qcd/action/gauge/Photon.h @@ -185,7 +185,7 @@ namespace QCD{ vol = vol * latt_size[d]; } invKHatSquared(weight); - weight = sqrt(vol*real(weight)); + weight = sqrt(vol)*sqrt(weight); zmSub(weight); } From a61e0df54b8836337a7b388620e62d57c502c953 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Mon, 14 May 2018 19:56:12 +0100 Subject: [PATCH 123/126] Travis fix for Lime --- .travis.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ad4e5b73..55f7c097 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,8 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc; fi install: + - export CWD=`pwd` + - echo $CWD - export CC=$CC$VERSION - export CXX=$CXX$VERSION - echo $PATH @@ -36,11 +38,22 @@ script: - ./bootstrap.sh - mkdir build - cd build - - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=none + - mkdir lime + - cd lime + - mkdir build + - cd build + - wget http://usqcd-software.github.io/downloads/c-lime/lime-1.3.2.tar.gz + - tar xf lime-1.3.2.tar.gz + - cd lime-1.3.2 + - ./configure --prefix=$CWD/build/lime/install + - make -j4 + - make install + - cd $CWD/build + - ../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 + - ../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 From fd3b2e945adedb99129f3aa0534ec62cce98d6e6 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 18 May 2018 20:48:24 +0100 Subject: [PATCH 124/126] Hadrons: don't right result with empty stem --- extras/Hadrons/Module.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Hadrons/Module.hpp b/extras/Hadrons/Module.hpp index dd038a21..2726da96 100644 --- a/extras/Hadrons/Module.hpp +++ b/extras/Hadrons/Module.hpp @@ -120,7 +120,7 @@ envTmp(type, name, Ls, env().getGrid(Ls)) MACRO_REDIRECT(__VA_ARGS__, envTmpLat5, envTmpLat4)(__VA_ARGS__) #define saveResult(ioStem, name, result)\ -if (env().getGrid()->IsBoss())\ +if (env().getGrid()->IsBoss() and !ioStem.empty())\ {\ makeFileDir(ioStem, env().getGrid());\ {\ From a0d399e5ce32d8bf0f51cceaa01cf920b907bde8 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 18 May 2018 20:49:26 +0100 Subject: [PATCH 125/126] Hadrons: yet other attempts at EMT NPR --- extras/Hadrons/Modules.hpp | 2 + .../Modules/MScalarSUN/TimeMomProbe.cc | 11 + .../Modules/MScalarSUN/TimeMomProbe.hpp | 241 ++++++++++++++++++ .../Hadrons/Modules/MScalarSUN/TwoPoint.hpp | 31 --- .../Hadrons/Modules/MScalarSUN/TwoPointNPR.cc | 11 + .../Modules/MScalarSUN/TwoPointNPR.hpp | 182 +++++++++++++ extras/Hadrons/Modules/MScalarSUN/Utils.hpp | 22 ++ extras/Hadrons/modules.inc | 4 + 8 files changed, 473 insertions(+), 31 deletions(-) create mode 100644 extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.hpp create mode 100644 extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.cc create mode 100644 extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp diff --git a/extras/Hadrons/Modules.hpp b/extras/Hadrons/Modules.hpp index 1a18eb3a..3b33eb6e 100644 --- a/extras/Hadrons/Modules.hpp +++ b/extras/Hadrons/Modules.hpp @@ -32,8 +32,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.cc b/extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.cc new file mode 100644 index 00000000..f22d08af --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.cc @@ -0,0 +1,11 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTimeMomProbe>; +template class Grid::Hadrons::MScalarSUN::TTimeMomProbe>; +template class Grid::Hadrons::MScalarSUN::TTimeMomProbe>; +template class Grid::Hadrons::MScalarSUN::TTimeMomProbe>; +template class Grid::Hadrons::MScalarSUN::TTimeMomProbe>; diff --git a/extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.hpp b/extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.hpp new file mode 100644 index 00000000..4807e865 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TimeMomProbe.hpp @@ -0,0 +1,241 @@ +#ifndef Hadrons_MScalarSUN_TimeMomProbe_hpp_ +#define Hadrons_MScalarSUN_TimeMomProbe_hpp_ + +#include +#include +#include +#include + +BEGIN_HADRONS_NAMESPACE + +/****************************************************************************** + * n-point functions O(t,p)*tr(phi(t_1,p_1)*...*phi(t_n,p_n)) * + ******************************************************************************/ +BEGIN_MODULE_NAMESPACE(MScalarSUN) + +class TimeMomProbePar: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TimeMomProbePar, + std::string, field, + std::vector, op, + std::vector>, timeMom, + std::string, output); +}; + +class TimeMomProbeResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TimeMomProbeResult, + std::string, op, + std::vector>, timeMom, + std::vector, data); +}; + +template +class TTimeMomProbe: public Module +{ +public: + typedef typename SImpl::Field Field; + typedef typename SImpl::SiteField::scalar_object Site; + typedef typename SImpl::ComplexField ComplexField; + typedef std::vector SlicedOp; +public: + // constructor + TTimeMomProbe(const std::string name); + // destructor + virtual ~TTimeMomProbe(void) {}; + // dependency relation + virtual std::vector getInput(void); + virtual std::vector getOutput(void); + // setup + virtual void setup(void); + // execution + virtual void execute(void); +private: + void vectorModulo(std::vector &v); +}; + +MODULE_REGISTER_TMP(TimeMomProbeSU2, TTimeMomProbe>, MScalarSUN); +MODULE_REGISTER_TMP(TimeMomProbeSU3, TTimeMomProbe>, MScalarSUN); +MODULE_REGISTER_TMP(TimeMomProbeSU4, TTimeMomProbe>, MScalarSUN); +MODULE_REGISTER_TMP(TimeMomProbeSU5, TTimeMomProbe>, MScalarSUN); +MODULE_REGISTER_TMP(TimeMomProbeSU6, TTimeMomProbe>, MScalarSUN); + +/****************************************************************************** + * TTimeMomProbe implementation * + ******************************************************************************/ +// constructor ///////////////////////////////////////////////////////////////// +template +TTimeMomProbe::TTimeMomProbe(const std::string name) +: Module(name) +{} + +// dependencies/products /////////////////////////////////////////////////////// +template +std::vector TTimeMomProbe::getInput(void) +{ + std::vector in = par().op; + + in.push_back(par().field); + + return in; +} + +template +std::vector TTimeMomProbe::getOutput(void) +{ + std::vector out; + + return out; +} + +// setup /////////////////////////////////////////////////////////////////////// +template +void TTimeMomProbe::setup(void) +{ + envTmpLat(ComplexField, "ftBuf"); + envTmpLat(Field, "ftMatBuf"); +} + +// execution /////////////////////////////////////////////////////////////////// +// NB: time is direction 0 +template +void TTimeMomProbe::vectorModulo(std::vector &v) +{ + for (unsigned int mu = 0; mu < env().getNd(); ++mu) + { + auto d = env().getDim(mu); + v[mu] = ((v[mu] % d) + d) % d; + } +} + +template +void TTimeMomProbe::execute(void) +{ + const unsigned int nd = env().getNd(); + const unsigned int nt = env().getDim(0); + double partVol = 1.; + std::set> timeMomSet; + std::vector>> timeMom; + std::vector> transferMom; + FFT fft(env().getGrid()); + std::vector dMask(nd, 1); + std::vector result; + std::map> slicedOp; + std::vector slicedProbe; + auto &phi = envGet(Field, par().field); + + envGetTmp(ComplexField, ftBuf); + envGetTmp(Field, ftMatBuf); + dMask[0] = 0; + for (unsigned int mu = 1; mu < nd; ++mu) + { + partVol *= env().getDim(mu); + } + timeMom.resize(par().timeMom.size()); + for (unsigned int p = 0; p < timeMom.size(); ++p) + { + for (auto &tms: par().timeMom[p]) + { + std::vector tm = strToVec(tms); + + timeMom[p].push_back(tm); + timeMomSet.insert(tm); + } + transferMom.push_back(std::vector(nd - 1, 0)); + for (auto &tm: timeMom[p]) + { + for (unsigned int j = 1; j < nd; ++j) + { + transferMom[p][j - 1] -= tm[j]; + } + } + LOG(Message) << "Probe " << p << " (" << timeMom[p].size() << " points) : " << std::endl; + LOG(Message) << " phi(t_i, p_i) for (t_i, p_i) in " << timeMom[p] << std::endl; + LOG(Message) << " operator with momentum " << transferMom[p] << std::endl; + } + LOG(Message) << "FFT: field '" << par().field << "'" << std::endl; + fft.FFT_dim_mask(ftMatBuf, phi, dMask, FFT::forward); + slicedProbe.resize(timeMom.size()); + for (unsigned int p = 0; p < timeMom.size(); ++p) + { + std::vector qt; + + LOG(Message) << "Making probe " << p << std::endl; + slicedProbe[p].resize(nt); + for (unsigned int t = 0; t < nt; ++t) + { + Site acc; + + for (unsigned int i = 0; i < timeMom[p].size(); ++i) + { + Site buf; + + qt = timeMom[p][i]; + qt[0] += t; + vectorModulo(qt); + peekSite(buf, ftMatBuf, qt); + if (i == 0) + { + acc = buf; + } + else + { + acc *= buf; + } + } + slicedProbe[p][t] = TensorRemove(trace(acc)); + } + //std::cout << slicedProbe[p]<< std::endl; + } + for (auto &o: par().op) + { + auto &op = envGet(ComplexField, o); + + slicedOp[o].resize(transferMom.size()); + LOG(Message) << "FFT: operator '" << o << "'" << std::endl; + fft.FFT_dim_mask(ftBuf, op, dMask, FFT::forward); + //std::cout << ftBuf << std::endl; + for (unsigned int p = 0; p < transferMom.size(); ++p) + { + std::vector qt(nd, 0); + + for (unsigned int j = 1; j < nd; ++j) + { + qt[j] = transferMom[p][j - 1]; + } + slicedOp[o][p].resize(nt); + for (unsigned int t = 0; t < nt; ++t) + { + TComplex buf; + + qt[0] = t; + vectorModulo(qt); + peekSite(buf, ftBuf, qt); + slicedOp[o][p][t] = TensorRemove(buf); + } + //std::cout << ftBuf << std::endl; + //std::cout << slicedOp[o][p] << std::endl; + } + } + LOG(Message) << "Making correlators" << std::endl; + for (auto &o: par().op) + for (unsigned int p = 0; p < timeMom.size(); ++p) + { + TimeMomProbeResult r; + + LOG(Message) << " <" << o << " probe_" << p << ">" << std::endl; + r.op = o; + r.timeMom = timeMom[p]; + r.data = makeTwoPoint(slicedOp[o][p], slicedProbe[p], 1./partVol); + result.push_back(r); + } + saveResult(par().output, "timemomprobe", result); +} + +END_MODULE_NAMESPACE + +END_HADRONS_NAMESPACE + +#endif // Hadrons_MScalarSUN_TimeMomProbe_hpp_ diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp index 8ee80242..2407f26f 100644 --- a/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPoint.hpp @@ -79,12 +79,6 @@ public: virtual void setup(void); // execution virtual void execute(void); -private: - // make 2-pt function - template - std::vector makeTwoPoint(const std::vector &sink, - const std::vector &source, - const double factor = 1.); private: std::vector> mom_; }; @@ -221,31 +215,6 @@ void TTwoPoint::execute(void) saveResult(par().output, "twopt", result); } -// make 2-pt function ////////////////////////////////////////////////////////// -template -template -std::vector TTwoPoint::makeTwoPoint( - const std::vector &sink, - const std::vector &source, - const double factor) -{ - assert(sink.size() == source.size()); - - unsigned int nt = sink.size(); - std::vector res(nt, 0.); - - for (unsigned int dt = 0; dt < nt; ++dt) - { - for (unsigned int t = 0; t < nt; ++t) - { - res[dt] += sink[(t+dt)%nt]*adj(source[t]); - } - res[dt] *= factor/static_cast(nt); - } - - return res; -} - END_MODULE_NAMESPACE END_HADRONS_NAMESPACE diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.cc b/extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.cc new file mode 100644 index 00000000..70fb2445 --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.cc @@ -0,0 +1,11 @@ +#include + +using namespace Grid; +using namespace Hadrons; +using namespace MScalarSUN; + +template class Grid::Hadrons::MScalarSUN::TTwoPointNPR>; +template class Grid::Hadrons::MScalarSUN::TTwoPointNPR>; +template class Grid::Hadrons::MScalarSUN::TTwoPointNPR>; +template class Grid::Hadrons::MScalarSUN::TTwoPointNPR>; +template class Grid::Hadrons::MScalarSUN::TTwoPointNPR>; diff --git a/extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp b/extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp new file mode 100644 index 00000000..4c2cdb0d --- /dev/null +++ b/extras/Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp @@ -0,0 +1,182 @@ +#ifndef Hadrons_MScalarSUN_TwoPointNPR_hpp_ +#define Hadrons_MScalarSUN_TwoPointNPR_hpp_ + +#include +#include +#include +#include + +BEGIN_HADRONS_NAMESPACE + +/****************************************************************************** + * TwoPointNPR * + ******************************************************************************/ +BEGIN_MODULE_NAMESPACE(MScalarSUN) + +class TwoPointNPRPar: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TwoPointNPRPar, + std::vector, op, + std::string, field, + std::string, output); +}; + +class TwoPointNPRResult: Serializable +{ +public: + GRID_SERIALIZABLE_CLASS_MEMBERS(TwoPointNPRResult, + std::string, op, + std::vector, data); +}; + +template +class TTwoPointNPR: public Module +{ +public: + typedef typename SImpl::Field Field; + typedef typename SImpl::SiteField::scalar_object Site; + typedef typename SImpl::ComplexField ComplexField; +public: + // constructor + TTwoPointNPR(const std::string name); + // destructor + virtual ~TTwoPointNPR(void) {}; + // dependency relation + virtual std::vector getInput(void); + virtual std::vector getOutput(void); + // setup + virtual void setup(void); + // execution + virtual void execute(void); +}; + +MODULE_REGISTER_TMP(TwoPointNPRSU2, TTwoPointNPR>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointNPRSU3, TTwoPointNPR>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointNPRSU4, TTwoPointNPR>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointNPRSU5, TTwoPointNPR>, MScalarSUN); +MODULE_REGISTER_TMP(TwoPointNPRSU6, TTwoPointNPR>, MScalarSUN); + +/****************************************************************************** + * TTwoPointNPR implementation * + ******************************************************************************/ +// constructor ///////////////////////////////////////////////////////////////// +template +TTwoPointNPR::TTwoPointNPR(const std::string name) +: Module(name) +{} + +// dependencies/products /////////////////////////////////////////////////////// +template +std::vector TTwoPointNPR::getInput(void) +{ + std::vector in = par().op; + + in.push_back(par().field); + + return in; +} + +template +std::vector TTwoPointNPR::getOutput(void) +{ + std::vector out; + + return out; +} + +// setup /////////////////////////////////////////////////////////////////////// +template +void TTwoPointNPR::setup(void) +{ + const unsigned int nl = env().getDim(0); + + for (unsigned int mu = 1; mu < env().getNd(); ++mu) + { + if (nl != env().getDim(mu)) + { + HADRONS_ERROR(Size, "non-cubic grid"); + } + } + envTmpLat(ComplexField, "ftBuf"); + envTmpLat(Field, "ftMatBuf"); +} + +// execution /////////////////////////////////////////////////////////////////// +template +void TTwoPointNPR::execute(void) +{ + const unsigned int nd = env().getNd(); + const unsigned int nl = env().getDim(0); + FFT fft(env().getGrid()); + std::vector result; + TwoPointNPRResult twoPtp1, twoPtp2; + auto &phi = envGet(Field, par().field); + bool doTwoPt = true; + + envGetTmp(ComplexField, ftBuf); + envGetTmp(Field, ftMatBuf); + LOG(Message) << "FFT: field '" << par().field << "'" << std::endl; + fft.FFT_all_dim(ftMatBuf, phi, FFT::forward); + for (auto &opName: par().op) + { + auto &op = envGet(ComplexField, opName); + std::vector p1, p2, p; + Site phip1, phip2; + TComplex opp; + TwoPointNPRResult r; + + LOG(Message) << "FFT: operator '" << opName << "'" << std::endl; + fft.FFT_all_dim(ftBuf, op, FFT::forward); + LOG(Message) << "Generating vertex function" << std::endl; + r.op = opName; + r.data.resize(nl); + if (doTwoPt) + { + twoPtp1.op = "phi_prop_p1"; + twoPtp1.data.resize(nl); + twoPtp2.op = "phi_prop_p2"; + twoPtp2.data.resize(nl); + } + for (unsigned int n = 0; n < nl; ++n) + { + p1.assign(nd, 0); + p2.assign(nd, 0); + p.assign(nd, 0); + // non-exceptional RI/SMOM kinematic + // p1 = mu*(1,1,0): in mom + // p2 = mu*(0,1,1): out mom + // p = p1 - p2 = mu*(1,0,-1) + // mu = 2*n*pi/L + p1[0] = n; + p1[1] = n; + p2[1] = n; + p2[2] = n; + p[0] = n; + p[2] = (nl - n) % nl; + peekSite(phip1, ftMatBuf, p1); + peekSite(phip2, ftMatBuf, p2); + peekSite(opp, ftBuf, p); + if (doTwoPt) + { + twoPtp1.data[n] = TensorRemove(trace(phip1*adj(phip1))); + twoPtp2.data[n] = TensorRemove(trace(phip2*adj(phip2))); + } + r.data[n] = TensorRemove(trace(phip2*adj(phip1))*opp); + } + if (doTwoPt) + { + result.push_back(twoPtp1); + result.push_back(twoPtp2); + } + result.push_back(r); + doTwoPt = false; + } + saveResult(par().output, "twoptnpr", result); +} + +END_MODULE_NAMESPACE + +END_HADRONS_NAMESPACE + +#endif // Hadrons_MScalarSUN_TwoPointNPR_hpp_ diff --git a/extras/Hadrons/Modules/MScalarSUN/Utils.hpp b/extras/Hadrons/Modules/MScalarSUN/Utils.hpp index 37a9e137..68009f5e 100644 --- a/extras/Hadrons/Modules/MScalarSUN/Utils.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/Utils.hpp @@ -89,6 +89,28 @@ inline void dmuAcc(Field &out, const Field &in, const unsigned int mu, const Dif } } +template +std::vector makeTwoPoint(const std::vector &sink, + const std::vector &source, + const double factor = 1.) +{ + assert(sink.size() == source.size()); + + unsigned int nt = sink.size(); + std::vector res(nt, 0.); + + for (unsigned int dt = 0; dt < nt; ++dt) + { + for (unsigned int t = 0; t < nt; ++t) + { + res[dt] += trace(sink[(t+dt)%nt]*source[t]); + } + res[dt] *= factor/static_cast(nt); + } + + return res; +} + inline std::string varName(const std::string name, const std::string suf) { return name + "_" + suf; diff --git a/extras/Hadrons/modules.inc b/extras/Hadrons/modules.inc index c2e84086..a1f34b95 100644 --- a/extras/Hadrons/modules.inc +++ b/extras/Hadrons/modules.inc @@ -32,6 +32,7 @@ modules_cc =\ Modules/MAction/DWF.cc \ Modules/MScalarSUN/TrPhi.cc \ Modules/MScalarSUN/Grad.cc \ + Modules/MScalarSUN/TimeMomProbe.cc \ Modules/MScalarSUN/TrMag.cc \ Modules/MScalarSUN/TrKinetic.cc \ Modules/MScalarSUN/EMT.cc \ @@ -39,6 +40,7 @@ modules_cc =\ Modules/MScalarSUN/TransProj.cc \ Modules/MScalarSUN/StochFreeField.cc \ Modules/MScalarSUN/TwoPoint.cc \ + Modules/MScalarSUN/TwoPointNPR.cc \ Modules/MScalarSUN/Div.cc \ Modules/MIO/LoadEigenPack.cc \ Modules/MIO/LoadBinary.cc \ @@ -80,8 +82,10 @@ modules_hpp =\ Modules/MAction/WilsonClover.hpp \ Modules/MAction/ZMobiusDWF.hpp \ Modules/MScalarSUN/StochFreeField.hpp \ + Modules/MScalarSUN/TwoPointNPR.hpp \ Modules/MScalarSUN/ShiftProbe.hpp \ Modules/MScalarSUN/Div.hpp \ + Modules/MScalarSUN/TimeMomProbe.hpp \ Modules/MScalarSUN/TrMag.hpp \ Modules/MScalarSUN/EMT.hpp \ Modules/MScalarSUN/TwoPoint.hpp \ From 255d4992e12ec585de06f4c0d3e20c6cee28b777 Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Fri, 18 May 2018 20:49:55 +0100 Subject: [PATCH 126/126] Hadrons: stochastic scalar SU(N) free field fix --- .../Modules/MScalarSUN/StochFreeField.hpp | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp index 6800de53..75ef3fde 100644 --- a/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp +++ b/extras/Hadrons/Modules/MScalarSUN/StochFreeField.hpp @@ -24,10 +24,10 @@ template class TStochFreeField: public Module { public: - typedef typename SImpl::Field Field; - typedef typename SImpl::ComplexField ComplexField; - typedef typename SImpl::Group Group; - typedef typename Group::LatticeAlgebraVector AlgebraField; + typedef typename SImpl::Field Field; + typedef typename SImpl::ComplexField ComplexField; + typedef typename SImpl::Group Group; + typedef typename SImpl::SiteField::scalar_object Site; public: // constructor TStochFreeField(const std::string name); @@ -87,6 +87,7 @@ void TStochFreeField::setup(void) create_weight = true; } envTmpLat(Field, "phift"); + envTmpLat(ComplexField, "ca"); envCreateLat(Field, getName()); } @@ -120,13 +121,27 @@ void TStochFreeField::execute(void) } LOG(Message) << "Generating random momentum-space field" << std::endl; envGetTmp(Field, phift); - Group::GaussianFundamentalLieAlgebraMatrix(rng, phift); + envGetTmp(ComplexField, ca); + phift = zero; + for (int a = 0; a < Nadj; ++a) + { + Site ta; + + gaussian(rng, ca); + Group::generator(a, ta); + phift += ca*ta; + } phift *= w; LOG(Message) << "Field Fourier transform" << std::endl; fft.FFT_all_dim(phi, phift, FFT::backward); - phi = (1./sqrt(2.))*(phi - adj(phi)); + phi = 0.5*(phi - adj(phi)); trphi2 = -TensorRemove(sum(trace(phi*phi))).real()/vol; LOG(Message) << "tr(phi^2)= " << trphi2 << std::endl; + + // ComplexField phi2(env().getGrid()); + + // phi2=trace(phi*phi); + // std::cout << phi2 << std::endl; } END_MODULE_NAMESPACE