SSAGES  0.8.5
Software Suite for Advanced General Ensemble Simulations
ResourceHandler.cpp
1 
20 #include <mxx/comm.hpp>
21 #include "CVs/CVManager.h"
22 #include "Drivers/DriverException.h"
23 #include "Loggers/Logger.h"
24 #include "Validator/ObjectRequirement.h"
25 #include "Methods/Method.h"
26 #include "ResourceHandler.h"
27 #include "Snapshot.h"
28 #include "Hook.h"
29 #include "schema.h"
30 
31 using namespace Json;
32 
33 namespace SSAGES
34 {
35  ResourceHandler::ResourceHandler(
36  mxx::comm&& world, mxx::comm&& comm, size_t walkerid,
37  const std::vector<Method*>& methods, CVManager* cvmanager) :
38  world_(std::move(world)), comm_(std::move(comm)), walkerid_(walkerid), nwalkers_(1),
39  methods_(methods), cvmanager_(cvmanager), hook_(nullptr), inputs_(0)
40  {
41  snapshot_ = new Snapshot(comm_, walkerid);
42  }
43 
45  {
46  hook->SetSnapshot(snapshot_);
47  hook->SetCVManager(cvmanager_);
48  for(auto& m : methods_)
49  hook->AddListener(m);
50  if(logger_ != nullptr) hook->AddListener(logger_);
51  hook_ = hook;
52  }
53 
54  ResourceHandler* ResourceHandler::Build(const Value& json, const MPI_Comm& world)
55  {
56  ObjectRequirement validator;
57  Value schema;
58  CharReaderBuilder rbuilder;
59  CharReader* reader = rbuilder.newCharReader();
60 
61  // Parse and validate top level schema. This just
62  // makes sure the proper fields exist and the correct
63  // types are specified in the input files.
64  reader->parse(JsonSchema::Simulation.c_str(),
65  JsonSchema::Simulation.c_str() + JsonSchema::Simulation.size(),
66  &schema, nullptr);
67  validator.Parse(schema, "#");
68  validator.Validate(json, "#");
69  if(validator.HasErrors())
70  throw BuildException(validator.GetErrors());
71 
72  // Get number of desired walkers and create array of input files.
73  auto nwalkers = json.get("walkers", 1).asUInt();
74  if(json["input"].isArray() && json["input"].size() != nwalkers)
75  throw BuildException({"#/input: Number of inputs do not match requested walkers."});
76 
77  std::vector<std::string> inputs;
78  for(size_t i = 0; i < nwalkers; ++i)
79  {
80  if(json["input"].isArray())
81  inputs.push_back(json["input"][static_cast<int>(i)].asString());
82  else
83  inputs.push_back(json["input"].asString());
84  }
85 
86  // Get basic MPI info and verify that the total number of
87  // cores are divisble by number of walkers.
88  auto wcomm = mxx::comm(world);
89  if(wcomm.size() % nwalkers != 0)
90  throw BuildException({"#/walkers: Allocated processors not divisible by number of walkers."});
91 
92  // Split communicators.
93  int ppw = wcomm.size()/nwalkers;
94  int walkerid = wcomm.rank()/ppw;
95  auto comm = wcomm.split(walkerid);
96 
97  // Build collective variables.
98  auto* cvmanager = new CVManager();
99  int icv = 0;
100  for(auto& cv : json["CVs"])
101  {
102  // Register name with CV manager, if it exists.
103  // Otherwise, register index as name to CV manager.
104  if(cv.isMember("name"))
105  {
106  CVManager::AddCVtoMap(cv["name"].asString(), icv);
107  }
108  else
109  {
110  CVManager::AddCVtoMap(std::to_string(icv), icv);
111  }
112 
113  // Build CV and add to manager.
114  cvmanager->AddCV(CollectiveVariable::BuildCV(cv, "#/CVs"));
115  ++icv;
116  }
117 
118  // Build methods.
119  std::vector<Method*> methods;
120  for(auto& m : json["methods"])
121  {
122  // Error will be thrown if lookup fails.
123  for(auto& cv : m["cvs"])
124  {
125  CVManager::LookupCV(cv, "#/methods");
126  }
127  methods.push_back(Method::BuildMethod(m, world, comm, "#/methods"));
128  }
129 
130  // Build logger.
131  Logger* l = nullptr;
132  if(json.isMember("logger"))
133  l = Logger::Build(json["logger"], world, comm, "#/logger");
134 
135  auto* rh = new ResourceHandler(std::move(world), std::move(comm), walkerid, methods, cvmanager);
136  rh->inputs_ = inputs;
137  rh->nwalkers_ = nwalkers;
138  rh->logger_ = l;
139  return rh;
140  }
141 
143  {
144  delete snapshot_;
145  delete cvmanager_;
146  for(auto& m : methods_)
147  delete m;
148  }
149 }
bool HasErrors()
Check if errors have occured.
Definition: Requirement.h:86
Collective variable manager.
Definition: CVManager.h:42
Class containing a snapshot of the current simulation in time.
Definition: Snapshot.h:47
STL namespace.
void SetSnapshot(class Snapshot *snapshot)
Sets the active snapshot.
Definition: Hook.cpp:84
void ConfigureHook(class Hook *hook)
Configure the Hook from given resources.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value to generate Requirement(s).
static int LookupCV(const Json::Value &cv, const std::string &path)
Get CV id from map.
Definition: CVManager.h:112
static void AddCVtoMap(const std::string &name, unsigned int id)
Register CV name with map.
Definition: CVManager.h:101
Exception to be thrown when building the Driver fails.
class CVManager * cvmanager_
Collective variable manager.
std::vector< std::string > GetErrors()
Get list of error messages.
Definition: Requirement.h:92
Base class for hooks into the simultion engines.
Definition: Hook.h:35
Requirements on an object.
mxx::comm comm_
MPI communicator containing processors for specific walker.
static ResourceHandler * Build(const Json::Value &json, const MPI_Comm &world)
Build a new ResourceHandler from JSON.
class Logger * logger_
CV logger.
static Method * BuildMethod(const Json::Value &json, const MPI_Comm &world, const MPI_Comm &comm, const std::string &path)
Build a derived method from JSON node.
Definition: Method.cpp:39
void AddListener(EventListener *listener)
Add a listener to the hook.
Definition: Hook.cpp:101
void SetCVManager(class CVManager *cvmanager)
Sets the current CV manager.
Definition: Hook.cpp:90
class Snapshot * snapshot_
Snapshot of system state (pointer).
Base class for logging SSAGES data.
Definition: Logger.h:41
class Hook * hook_
Hook pointer.
Class that handles SSAGES resources for a simulation.
ResourceHandler(mxx::comm &&world, mxx::comm &&comm, size_t walkerid, const std::vector< class Method * > &methods, class CVManager *cvmanager)
Constructor.
static Logger * Build(const Json::Value &json, const MPI_Comm &world, const MPI_Comm &comm, const std::string &path)
Build a Logger from JSON node.
Definition: Logger.cpp:75
std::vector< class Method * > methods_
Vector of advanced sampling methods.
static CollectiveVariable * BuildCV(const Json::Value &json, const std::string &path)
Set up collective variable.
virtual void Validate(const Value &json, const std::string &path) override
Validate JSON value.