SSAGES  0.8.3
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, NULL);
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  if(cv.isMember("name"))
104  CVManager::AddCVtoMap(cv["name"].asString(), icv);
105 
106  // Build CV and add to manager.
107  cvmanager->AddCV(CollectiveVariable::BuildCV(cv, "#/CVs"));
108  ++icv;
109  }
110 
111  // Build methods.
112  std::vector<Method*> methods;
113  for(auto& m : json["methods"])
114  {
115  // Check CVs specified in each method.
116  for(auto& cv : m["cvs"])
117  {
118  if(cv.isString())
119  {
120  CVManager::LookupCV(cv.asString());
121  }
122  else if(cv >= icv || cv < 0)
123  {
124  throw BuildException({"#/methods: CV mask index of " + cv.asString() + " does not exist. " +
125  "Index must be nonnegative and less than " + std::to_string(icv) + "."});
126  }
127  }
128  methods.push_back(Method::BuildMethod(m, world, comm, "#/methods"));
129  }
130 
131  // Build logger.
132  Logger* l = nullptr;
133  if(json.isMember("logger"))
134  l = Logger::Build(json["logger"], world, comm, "#/logger");
135 
136  auto* rh = new ResourceHandler(std::move(world), std::move(comm), walkerid, methods, cvmanager);
137  rh->inputs_ = inputs;
138  rh->nwalkers_ = nwalkers;
139  rh->logger_ = l;
140  return rh;
141  }
142 
144  {
145  delete snapshot_;
146  delete cvmanager_;
147  for(auto& m : methods_)
148  delete m;
149  }
150 }
bool HasErrors()
Check if errors have occured.
Definition: Requirement.h:86
Collective variable manager.
Definition: CVManager.h:40
Class containing a snapshot of the current simulation in time.
Definition: Snapshot.h:43
STL namespace.
ResourceHandler(mxx::comm &&world, mxx::comm &&comm, size_t walkerid, const std::vector< class Method *> &methods, class CVManager *cvmanager)
Constructor.
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 void AddCVtoMap(const std::string &name, unsigned int id)
Register CV name with map.
Definition: CVManager.h:100
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
static int LookupCV(const std::string &name)
Get CV id from map.
Definition: CVManager.h:110
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.
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.