/******************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: programs/Hadrons/Environment.hpp 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. *******************************************************************************/ #ifndef Hadrons_Environment_hpp_ #define Hadrons_Environment_hpp_ #include #include BEGIN_HADRONS_NAMESPACE /****************************************************************************** * Global environment * ******************************************************************************/ // forward declaration of Module class ModuleBase; class Environment { SINGLETON(Environment); public: typedef std::unique_ptr ModPt; typedef std::unique_ptr GridPt; typedef std::unique_ptr GridRbPt; typedef FermionOperator FMat; typedef std::unique_ptr FMatPt; typedef std::function Solver; typedef std::unique_ptr RngPt; typedef std::unique_ptr LatticePt; private: struct ObjInfo { unsigned int size{0}, Ls{0}; bool isRegistered{false}; }; public: // dry run void dryRun(const bool isDry); bool isDryRun(void) const; // trajectory number void setTrajectory(const unsigned int traj); unsigned int getTrajectory(void) const; // grids void createGrid(const unsigned int Ls); GridCartesian * getGrid(const unsigned int Ls = 1) const; GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const; // random number generator void setSeed(const std::vector &seed); GridParallelRNG * get4dRng(void) const; // module management void createModule(const std::string name, const std::string type, XmlReader &reader); ModuleBase * getModule(const unsigned int address) const; ModuleBase * getModule(const std::string name) const; template M * getModule(const unsigned int address) const; template M * getModule(const std::string name) const; unsigned int getModuleAddress(const std::string name) const; std::string getModuleName(const unsigned int address) const; std::string getModuleType(const unsigned int address) const; std::string getModuleType(const std::string name) const; bool hasModule(const unsigned int address) const; bool hasModule(const std::string name) const; Graph makeModuleGraph(void) const; unsigned int executeProgram(const std::vector &p); unsigned int executeProgram(const std::vector &p); // lattice store template T * create(const std::string name); template T * get(const std::string name) const; bool hasLattice(const unsigned int address) const; bool hasLattice(const std::string name) const; void freeLattice(const unsigned int address); void freeLattice(const std::string name); template unsigned int lattice4dSize(void) const; // fermion actions void addFermionMatrix(const std::string name, FMat *mat); FMat * getFermionMatrix(const std::string name) const; bool hasFermionMatrix(const unsigned int address) const; bool hasFermionMatrix(const std::string name) const; void freeFermionMatrix(const unsigned int address); void freeFermionMatrix(const std::string name); // solvers void addSolver(const std::string name, Solver s); bool hasSolver(const unsigned int address) const; bool hasSolver(const std::string name) const; void setSolverAction(const std::string name, const std::string actionName); std::string getSolverAction(const std::string name) const; void callSolver(const std::string name, LatticeFermion &sol, const LatticeFermion &src) const; // general memory management void registerObject(const unsigned int address, const unsigned int size, const unsigned int Ls = 1); void registerObject(const std::string name, const unsigned int size, const unsigned int Ls = 1); template void registerLattice(const unsigned int address, const unsigned int Ls = 1); template void registerLattice(const std::string name, const unsigned int Ls = 1); unsigned int getObjectAddress(const std::string name) const; std::string getObjectName(const unsigned int address) const; unsigned int getObjectSize(const unsigned int address) const; unsigned int getObjectSize(const std::string name) const; unsigned int getObjectLs(const unsigned int address) const; unsigned int getObjectLs(const std::string name) const; bool hasObject(const unsigned int address) const; bool hasObject(const std::string name) const; bool hasRegisteredObject(const unsigned int address) const; bool hasRegisteredObject(const std::string name) const; bool isObject5d(const unsigned int address) const; bool isObject5d(const std::string name) const; long unsigned int getTotalSize(void) const; void addOwnership(const unsigned int owner, const unsigned int property); void addOwnership(const std::string owner, const std::string property); bool hasOwners(const unsigned int address) const; bool hasOwners(const std::string name) const; bool freeObject(const unsigned int address); bool freeObject(const std::string name); void freeAll(void); void printContent(void); private: // general bool dryRun_{false}; unsigned int traj_, locVol_; // grids GridPt grid4d_; std::map grid5d_; GridRbPt gridRb4d_; std::map gridRb5d_; // random number generator RngPt rng4d_; // module and related maps std::vector module_; std::vector moduleType_; std::vector moduleName_; std::map moduleAddress_; std::vector> moduleInput_; // lattice store std::map lattice_; // fermion matrix store std::map fMat_; // solver store & solver/action map std::map solver_; std::map solverAction_; // object register std::vector object_; std::vector objectName_; std::map objectAddress_; std::vector objectModule_; std::vector> owners_; std::vector> properties_; }; /****************************************************************************** * template implementation * ******************************************************************************/ template M * Environment::getModule(const unsigned int address) const { if (auto *pt = dynamic_cast(getModule(address))) { return pt; } else { HADRON_ERROR("module '" + moduleName_[address] + "' does not have type " + typeName() + "(object type: " + typeName(*module_.at(address).get()) + ")"); } } template M * Environment::getModule(const std::string name) const { return getModule(getModuleAddress(name)); } template unsigned int Environment::lattice4dSize(void) const { return sizeof(typename T::vector_object)/getGrid()->Nsimd(); } template T * Environment::create(const std::string name) { auto i = getObjectAddress(name); GridCartesian *g = getGrid(getObjectLs(i)); lattice_[i].reset(new T(g)); return dynamic_cast(lattice_[i].get()); } template T * Environment::get(const std::string name) const { if (hasLattice(name)) { auto i = getObjectAddress(name); if (auto pt = dynamic_cast(lattice_.at(i).get())) { return pt; } else { HADRON_ERROR("object '" + name + "' does not have type " + typeName() + "(object type: " + typeName(*lattice_.at(i).get()) + ")"); } } else { HADRON_ERROR("no lattice with name '" + name + "'"); return nullptr; } } template void Environment::registerLattice(const unsigned int address, const unsigned int Ls) { createGrid(Ls); registerObject(address, Ls*lattice4dSize()); } template void Environment::registerLattice(const std::string name, const unsigned int Ls) { createGrid(Ls); registerObject(name, Ls*lattice4dSize()); } END_HADRONS_NAMESPACE #endif // Hadrons_Environment_hpp_