From ae682674e0dc1bae84c3a0e9c5225062e031267b Mon Sep 17 00:00:00 2001 From: Antonin Portelli Date: Wed, 13 Jan 2016 20:23:51 -0800 Subject: [PATCH] Hadrons: first full implementation of the scheduler --- programs/Hadrons/Application.cc | 63 ++++++++++++--- programs/Hadrons/Application.hpp | 22 +++--- programs/Hadrons/CMeson.cc | 8 +- programs/Hadrons/CMeson.hpp | 6 +- programs/Hadrons/Environment.cc | 130 ++++++++++++++++++++++++++++++- programs/Hadrons/Environment.hpp | 23 ++++++ programs/Hadrons/Global.hpp | 3 +- programs/Hadrons/Graph.hpp | 24 +++--- programs/Hadrons/MQuark.cc | 14 +++- programs/Hadrons/MQuark.hpp | 7 +- programs/Hadrons/Module.cc | 9 +++ programs/Hadrons/Module.hpp | 10 +-- 12 files changed, 264 insertions(+), 55 deletions(-) diff --git a/programs/Hadrons/Application.cc b/programs/Hadrons/Application.cc index 0fad9c1e..c8c44adc 100644 --- a/programs/Hadrons/Application.cc +++ b/programs/Hadrons/Application.cc @@ -83,6 +83,7 @@ void Application::parseParameterFile(void) { associatedModule_[n] = id.name; } + input_[id.name] = module_[id.name]->getInput(); } while (reader.nextElement("module")); pop(reader); pop(reader); @@ -113,19 +114,35 @@ void Application::schedule(void) } // topological sort - std::map> m; - unsigned int k = 0; + unsigned int k = 0; std::vector> con = moduleGraph.getConnectedComponents(); LOG(Message) << "Program:" << std::endl; for (unsigned int i = 0; i < con.size(); ++i) { std::vector> t = con[i].allTopoSort(); + int memPeak, minMemPeak = -1; + unsigned int bestInd; + bool msg; - m = makeDependencyMatrix(t); - for (unsigned int j = 0; j < t[0].size(); ++j) + env_.dryRun(true); + for (unsigned int p = 0; p < t.size(); ++p) { - program_.push_back(t[0][j]); + msg = HadronsLogMessage.isActive(); + HadronsLogMessage.Active(false); + memPeak = execute(t[p]); + if ((memPeak < minMemPeak) or (minMemPeak < 0)) + { + minMemPeak = memPeak; + bestInd = p; + } + HadronsLogMessage.Active(msg); + env_.freeAll(); + } + env_.dryRun(false); + for (unsigned int j = 0; j < t[bestInd].size(); ++j) + { + program_.push_back(t[bestInd][j]); LOG(Message) << std::setw(4) << std::right << k << ": " << program_[k] << std::endl; k++; @@ -142,16 +159,42 @@ void Application::configLoop(void) { LOG(Message) << "Starting measurement for trajectory " << t << std::endl; - execute(); + execute(program_); + env_.freeAll(); } } -void Application::execute(void) +unsigned int Application::execute(const std::vector &program) { - for (unsigned int i = 0; i < program_.size(); ++i) + unsigned int memPeak = 0; + + for (unsigned int i = 0; i < program.size(); ++i) { - LOG(Message) << "Measurement step (" << i+1 << "/" << program_.size() + LOG(Message) << "Measurement step (" << i+1 << "/" << program.size() << ")" << std::endl; - (*module_[program_[i]])(env_); + (*module_[program[i]])(env_); + LOG(Message) << "allocated propagators: " << env_.nProp() << std::endl; + if (env_.nProp() > memPeak) + { + memPeak = env_.nProp(); + } + for (auto &n: associatedModule_) + { + bool canFree = true; + + for (unsigned int j = i + 1; j < program.size(); ++j) + { + auto &in = input_[program[j]]; + auto it = std::find(in.begin(), in.end(), n.first); + canFree = canFree and (it == in.end()); + } + if (canFree and env_.propExists(n.first)) + { + LOG(Message) << "freeing '" << n.first << "'" << std::endl; + env_.free(n.first); + } + } } + + return memPeak; } diff --git a/programs/Hadrons/Application.hpp b/programs/Hadrons/Application.hpp index 7b53af98..fd583fce 100644 --- a/programs/Hadrons/Application.hpp +++ b/programs/Hadrons/Application.hpp @@ -51,8 +51,7 @@ class GlobalPar: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(GlobalPar, - std::vector, latticeSize, - ConfigPar, configs); + ConfigPar, configs); }; /****************************************************************************** @@ -75,16 +74,17 @@ private: // schedule computation void schedule(void); // program execution - void configLoop(void); - void execute(void); + void configLoop(void); + unsigned int execute(const std::vector &program); private: - std::string parameterFileName_; - GlobalPar par_; - Environment &env_; - ModuleFactory &modFactory_; - std::map> module_; - std::map associatedModule_; - std::vector program_; + std::string parameterFileName_; + GlobalPar par_; + Environment &env_; + ModuleFactory &modFactory_; + std::map> module_; + std::map associatedModule_; + std::map> input_; + std::vector program_; }; END_HADRONS_NAMESPACE diff --git a/programs/Hadrons/CMeson.cc b/programs/Hadrons/CMeson.cc index 32febc13..e93cb18c 100644 --- a/programs/Hadrons/CMeson.cc +++ b/programs/Hadrons/CMeson.cc @@ -52,13 +52,11 @@ std::vector CMeson::getOutput(void) } // memory footprint //////////////////////////////////////////////////////////// -double CMeson::nCreatedProp(void) -{ - return 0.; -} +void CMeson::allocate(Environment &env) +{} // execution /////////////////////////////////////////////////////////////////// -void CMeson::operator()(Environment &env) +void CMeson::execute(Environment &env) { LOG(Message) << "computing meson contraction '" << getName() << "'" << std::endl; diff --git a/programs/Hadrons/CMeson.hpp b/programs/Hadrons/CMeson.hpp index 7f13ce9a..843ae00b 100644 --- a/programs/Hadrons/CMeson.hpp +++ b/programs/Hadrons/CMeson.hpp @@ -50,10 +50,10 @@ public: // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); - // memory footprint - virtual double nCreatedProp(void); + // allocation + virtual void allocate(Environment &env); // execution - virtual void operator()(Environment &env); + virtual void execute(Environment &env); private: Par par_; }; diff --git a/programs/Hadrons/Environment.cc b/programs/Hadrons/Environment.cc index 391f0c04..fb9052f0 100644 --- a/programs/Hadrons/Environment.cc +++ b/programs/Hadrons/Environment.cc @@ -20,6 +20,7 @@ #include using namespace Grid; +using namespace QCD; using namespace Hadrons; /****************************************************************************** @@ -27,5 +28,132 @@ using namespace Hadrons; ******************************************************************************/ // constructor ///////////////////////////////////////////////////////////////// Environment::Environment(void) -{} +{ + grid4d_.reset(SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi())); +} +// dry run ///////////////////////////////////////////////////////////////////// +void Environment::dryRun(const bool isDry) +{ + dryRun_ = isDry; +} + +bool Environment::isDryRun(void) +{ + return dryRun_; +} + +// quark propagators /////////////////////////////////////////////////////////// +void Environment::addProp(const std::string name, const unsigned int Ls) +{ + if (propExists(name)) + { + HADRON_ERROR("propagator '" + name + "' already exists"); + } + if (Ls > 1) + { + GridCartesian *pt; + + try + { + pt = grid5d_.at(Ls).get(); + } + catch(std::out_of_range &) + { + grid5d_[Ls].reset(SpaceTimeGrid::makeFiveDimGrid(Ls, + grid4d_.get())); + pt = grid5d_[Ls].get(); + } + if (!isDryRun()) + { + prop_[name].reset(new LatticePropagator(pt)); + } + else + { + prop_[name].reset(nullptr); + } + propSize_[name] = Ls; + } + else + { + if (!isDryRun()) + { + prop_[name].reset(new LatticePropagator(grid4d_.get())); + } + else + { + prop_[name].reset(nullptr); + } + propSize_[name] = 1; + } +} + +void Environment::freeProp(const std::string name) +{ + if (propExists(name)) + { + prop_.erase(name); + propSize_.erase(name); + } + else + { + HADRON_ERROR("trying to free unknown propagator '" + name + "'"); + } +} + +LatticePropagator * Environment::getProp(const std::string name) +{ + if (propExists(name)) + { + return prop_[name].get(); + } + else + { + HADRON_ERROR("propagator '" + name + "' unknown"); + + return nullptr; + } +} + +bool Environment::propExists(const std::string name) +{ + auto it = prop_.find(name); + + if (it == prop_.end()) + { + return false; + } + else + { + return true; + } +} + +unsigned int Environment::nProp(void) +{ + unsigned int size = 0; + + for (auto &s: propSize_) + { + size += s.second; + } + + return size; +} + +// general free //////////////////////////////////////////////////////////////// +void Environment::free(const std::string name) +{ + if (propExists(name)) + { + freeProp(name); + } +} + +void Environment::freeAll(void) +{ + prop_.clear(); + propSize_.clear(); +} diff --git a/programs/Hadrons/Environment.hpp b/programs/Hadrons/Environment.hpp index 62da9839..66576658 100644 --- a/programs/Hadrons/Environment.hpp +++ b/programs/Hadrons/Environment.hpp @@ -30,6 +30,29 @@ BEGIN_HADRONS_NAMESPACE class Environment { SINGLETON(Environment); +public: + typedef std::unique_ptr GridPt; + typedef std::unique_ptr PropPt; +public: + // dry run + void dryRun(const bool isDry); + bool isDryRun(void); + // quark propagators + void addProp(const std::string name, + const unsigned int Ls = 1); + void freeProp(const std::string name); + LatticePropagator * getProp(const std::string name); + bool propExists(const std::string name); + unsigned int nProp(void); + // general free + void free(const std::string name); + void freeAll(void); +private: + bool dryRun_{false}; + GridPt grid4d_; + std::map grid5d_; + std::map prop_; + std::map propSize_; }; END_HADRONS_NAMESPACE diff --git a/programs/Hadrons/Global.hpp b/programs/Hadrons/Global.hpp index 2294adef..693a9829 100644 --- a/programs/Hadrons/Global.hpp +++ b/programs/Hadrons/Global.hpp @@ -26,7 +26,8 @@ #define BEGIN_HADRONS_NAMESPACE \ namespace Hadrons {\ -using namespace Grid; +using namespace Grid;\ +using namespace QCD; #define END_HADRONS_NAMESPACE } BEGIN_HADRONS_NAMESPACE diff --git a/programs/Hadrons/Graph.hpp b/programs/Hadrons/Graph.hpp index a2747c1a..7440975b 100644 --- a/programs/Hadrons/Graph.hpp +++ b/programs/Hadrons/Graph.hpp @@ -190,27 +190,27 @@ unsigned int Graph::size(void) const template bool Graph::gotValue(const T &value) const { - try - { - isMarked_.at(value); - } - catch (std::out_of_range &) + auto it = isMarked_.find(value); + + if (it == isMarked_.end()) { return false; } - - return true; + else + { + return true; + } } // vertex marking ////////////////////////////////////////////////////////////// template void Graph::mark(const T &value, const bool doMark) { - try + if (gotValue(value)) { - isMarked_.at(value) = doMark; + isMarked_[value] = doMark; } - catch (std::out_of_range &) + else { HADRON_ERROR("vertex " << value << " does not exists"); } @@ -240,11 +240,11 @@ void Graph::unmarkAll(void) template bool Graph::isMarked(const T &value) const { - try + if (gotValue(value)) { return isMarked_.at(value); } - catch (std::out_of_range &) + else { HADRON_ERROR("vertex " << value << " does not exists"); diff --git a/programs/Hadrons/MQuark.cc b/programs/Hadrons/MQuark.cc index 2cc27311..f2ae3ee9 100644 --- a/programs/Hadrons/MQuark.cc +++ b/programs/Hadrons/MQuark.cc @@ -49,14 +49,20 @@ std::vector MQuark::getOutput(void) return out; } -// memory footprint -double MQuark::nCreatedProp(void) +// allocation ////////////////////////////////////////////////////////////////// +void MQuark::allocate(Environment &env) { - return static_cast((par_.Ls > 1) ? par_.Ls + 1 : 1); + env.addProp(getName()); + quark_ = env.getProp(getName()); + if (par_.Ls > 1) + { + env.addProp(getName() + "_5d", par_.Ls); + quark5d_ = env.getProp(getName() + "_5d"); + } } // execution -void MQuark::operator()(Environment &env) +void MQuark::execute(Environment &env) { LOG(Message) << "computing quark propagator '" << getName() << "'" << std::endl; diff --git a/programs/Hadrons/MQuark.hpp b/programs/Hadrons/MQuark.hpp index ae1efa12..f5ab94fb 100644 --- a/programs/Hadrons/MQuark.hpp +++ b/programs/Hadrons/MQuark.hpp @@ -47,12 +47,13 @@ public: // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); - // memory footprint - virtual double nCreatedProp(void); + // allocation + virtual void allocate(Environment &env); // execution - virtual void operator()(Environment &env); + virtual void execute(Environment &env); private: Par par_; + LatticePropagator *quark_{nullptr}, *quark5d_{nullptr}; }; MODULE_REGISTER(MQuark); diff --git a/programs/Hadrons/Module.cc b/programs/Hadrons/Module.cc index 5267449c..a5809155 100644 --- a/programs/Hadrons/Module.cc +++ b/programs/Hadrons/Module.cc @@ -35,3 +35,12 @@ std::string Module::getName(void) const { return name_; } + +void Module::operator()(Environment &env) +{ + allocate(env); + if (!env.isDryRun()) + { + execute(env); + } +} diff --git a/programs/Hadrons/Module.hpp b/programs/Hadrons/Module.hpp index bf82a9e7..a8d3b40e 100644 --- a/programs/Hadrons/Module.hpp +++ b/programs/Hadrons/Module.hpp @@ -21,6 +21,7 @@ #define Hadrons_Module_hpp_ #include +#include BEGIN_HADRONS_NAMESPACE @@ -43,8 +44,6 @@ static mod##Registrar mod##RegistrarInstance; /****************************************************************************** * Module * ******************************************************************************/ -class Environment; - class Module { public: @@ -59,10 +58,11 @@ public: // dependency relation virtual std::vector getInput(void) = 0; virtual std::vector getOutput(void) = 0; - // memory footprint - virtual double nCreatedProp(void) = 0; + // allocation + virtual void allocate(Environment &env) = 0; // execution - virtual void operator()(Environment &env) = 0; + void operator()(Environment &env); + virtual void execute(Environment &env) = 0; private: std::string name_; };