gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
diagnostics.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
24 
25 #include "gambit/Core/core.hpp"
32 #include "gambit/cmake/cmake_variables.hpp"
33 
34 #include <memory>
35 #include <string>
36 
37 namespace Gambit
38 {
39 
42  {
43  YAML::Node gambit_bits_yaml = YAML::LoadFile(GAMBIT_DIR "/config/gambit_bits.yaml");
44  auto gambit_bits = gambit_bits_yaml["gambit_bits"].as<std::vector<std::string>>();
45 
46  // We need to manually add this here, can not be crawled by our script.
47  // We want to sort it again to keep alphabetical ordering from the python script after adding bits explicitly here.
48  gambit_bits.emplace_back(std::string{"BackendIniBit"});
49  std::sort(gambit_bits.begin(), gambit_bits.end());
50 
51  table_formatter table("Modules", "Status", "#functions");
52  table.padding(1);
53  table.capitalize_title();
54  table.default_widths(25);
55 
56  for (const auto &bit: gambit_bits)
57  {
58  table << bit;
59 
60  auto result = std::find(std::begin(modules), std::end(modules), bit);
61  if (result == std::end(modules))
62  {
63  table.red() << "ditched";
64  table << "n/a";
65  }
66  else
67  {
68  int nf = 0;
69  for (const auto &functor : functorList)
70  {
71  if (functor->origin() == bit) nf++;
72  }
73  table.green() << "OK";
74  table << nf;
75  }
76  }
77 
78  std::stringstream out;
79  out << table.str();
80  print_to_screen(out.str(), "module");
81  }
82 
85  {
86  bool all_good = true;
87  table_formatter table("Backends", "Version", "Path to lib", "Status ", " #func ", "#types ", "#ctors");
88  table.padding(1);
89  table.capitalize_title();
90  table.default_widths(18, 7, 70, 13, 3, 3);
91 
92  // Loop over all registered backends
93  for (const auto &backend : backend_versions)
94  {
95  // Loop over all registered versions of this backend
96  for (const auto &version : backend.second)
97  {
98  int nfuncs = 0;
99  int ntypes = 0;
100  int nctors = 0;
101 
102  // Retrieve the status and path info.
103  const str path = backendData->path(backend.first, version); // Get the path of this backend
104  const str status = backend_status(backend.first, version, all_good); // Save the status of this backend
105 
106  // Count up the number of functions in this version of the backend, using the registered functors.
107  for (const auto &functor : backendFunctorList)
108  {
109  if (functor->origin() == backend.first and functor->version() == version) nfuncs++; // If backend matches, increment the count of the functions in this version
110  }
111 
112  // Do things specific to versions that provide classes
113  if (backendData->classloader.at(backend.first + version))
114  {
115  const std::set<str> classes = backendData->classes.at(backend.first + version); // Retrieve classes loaded by this version
116  ntypes = classes.size(); // Get the number of classes loaded by this backend
117  for (const auto &class_ : classes) // class is a C++ keyword, so use class_ here which allows the same readability.
118  {
119  nctors += backendData->factory_args.at(backend.first + version + class_).size(); // Add the number of factories for this class to the total
120  }
121  }
122 
123  // Print the info
124  const str firstentry = (&version == std::addressof(*backend.second.begin()) ? backend.first : "");
125  table << firstentry << version << path;
126  if (status == "OK")
127  table.green() << status;
128  else
129  table.red() << status;
130  table << " " + std::to_string(nfuncs) << std::to_string(ntypes) << std::to_string(nctors);
131  }
132  }
133 
134  std::stringstream out;
135  out << "All relative paths are given with reference to " << GAMBIT_DIR << ".";
136  if (all_good)
137  out << endl
138  << endl
139  << "\033[032m"
140  << "All your backend are belong to us."
141  << "\033[0m" << endl;
142  out << endl;
143  out << table.str();
144  print_to_screen(out.str(), "backend");
145  }
146 
149  {
150  table_formatter table("Model", "Parent", "Parameters");
151  table.default_widths(35);
152  table.padding(1);
153  table.capitalize_title();
154 
155  for (const auto &functor : primaryModelFunctorList)
156  {
157  const str model = functor->origin();
158  const str parentof = modelInfo->get_parent(model);
159  const int nparams = functor->valuePtr()->getNumberOfPars();
160  table << model << parentof << nparams;
161  }
162 
163  std::stringstream out;
164 #ifdef HAVE_GRAPHVIZ
165  // Create and spit out graph of the model hierarchy.
166  const str graphfile = Utils::runtime_scratch() + "GAMBIT_model_hierarchy.gv";
167  ModelHierarchy modelGraph(*modelInfo, primaryModelFunctorList, graphfile, false);
168  out << endl << "Created graphviz model hierarchy graph in " + graphfile + "." << endl;
169  out << endl << "To get postscript plot of model hierarchy, please run: " << endl;
170  out << GAMBIT_DIR << "/Core/scripts/./graphviz.sh " + graphfile << endl;
171 #else
172  out << endl << "To get postscript plot of model hierarchy, please install graphviz, rerun cmake and remake GAMBIT." << endl;
173 #endif
174  out << table.str();
175  print_to_screen(out.str(), "model");
176  }
177 
180  {
181 
182  // Default, list-format output header
183  table_formatter table("Capabilities", "Available in (modules/models)", "Available in (backends)");
184  table.padding(1);
185  table.capitalize_title();
186  table.default_widths(35, 25);
187  for (const auto &capability : capabilities)
188  {
189  // Make sets of matching modules and backends
190  std::set<str> modset;
191  for (const auto &functor : functorList)
192  {
193  if (functor->capability() == capability) modset.insert(functor->origin());
194  }
195  std::set<str> beset;
196  for (const auto &functor : backendFunctorList)
197  {
198  if (functor->capability() == capability) beset.insert(functor->origin());
199  }
200 
201  // Make strings out of the sets
202  std::string mods("");
203  for (const auto &mod : modset)
204  {
205  if (&mod != std::addressof(*modset.begin())) mods += ", ";
206  mods += mod;
207  }
208  std::string bes("");
209  for (const auto &be : beset)
210  {
211  if (&be != std::addressof(*beset.begin())) bes += ", ";
212  bes += be;
213  }
214 
215  // Identify the primary model parameters with their models.
216  if (mods.empty() and bes.empty()) mods = capability.substr(0, capability.length() - 11);
217 
218  // Print the entry in the table (list format)
219  table << capability << mods << bes;
220  }
221  std::stringstream out;
222  out << table.str();
223  print_to_screen(out.str(), "capability");
224  }
225 
228  {
229  // Import scanner plugin info from ScannerBit
230  const std::string output = Scanner::Plugins::plugin_info().print_all("scanner");
231  print_to_screen(output, "scanners");
232  }
233 
236  {
237  const std::string output = Scanner::Plugins::plugin_info().print_all("objective");
238  print_to_screen(output, "objectives");
239  }
240 
242  {
243  const std::string output = Scanner::Plugins::plugin_info().print_priors("priors");
244  print_to_screen(output, "priors");
245  }
246 
248  {
249  if (command != "priors")
250  {
251  const std::string output = Scanner::Plugins::plugin_info().print_priors(command);
252  print_to_screen(output, command);
253  }
254  }
255 
258  {
259  std::stringstream out;
260  for (const auto &module : modules)
261  {
262  if (command == module)
263  {
264  out << "Information for module " << module << "." << std::endl << std::endl;
265  table_formatter table("", "", "", "LOOP MANAGER:", "DEPENDENCIES / BACKEND REQUIREMENTS");
266  table.new_titles("Function", "Capability", "Result Type", " IS NEEDS", "[type] {type}");
267  table.padding(1);
268  table.capitalize_title();
269  table.default_widths(30, 35, 35, 19, 27);
270 
271  for (const auto &functor : functorList)
272  {
273  if (functor->origin() == module) // Module matches
274  {
275  const str f = functor->name();
276  const str c = functor->capability();
277  const str t = functor->type();
278  const str islm = functor->canBeLoopManager() ? "Yes" : "No ";
279  const str nlm = functor->loopManagerCapability();
280  const std::set<sspair> deps = functor->dependencies();
281  const std::set<sspair> reqs = functor->backendreqs();
282  table.no_newline() << f << c << t << (" " + islm + " " + nlm);
283 
284  if (not deps.empty())
285  {
286  for (const auto &dep : deps)
287  {
288  if (&dep != std::addressof(*deps.begin()))
289  table.no_newline() << ""
290  << ""
291  << ""
292  << "" << dep.first + " [" + dep.second + "]";
293  else
294  table << dep.first + " [" + dep.second + "]";
295  }
296  }
297  if (not reqs.empty())
298  {
299  for (const auto &req : reqs)
300  {
301  if (&req != std::addressof(*reqs.begin()) or not deps.empty())
302  table.no_newline() << ""
303  << ""
304  << ""
305  << "" << req.first + " {" + req.second + "}";
306  else
307  table << req.first + " {" + req.second + "}";
308  }
309  }
310  if (reqs.empty() and deps.empty()) table << "";
311  table.newline(table.row_pos() - 1);
312  }
313  }
314  out << table.str();
315  break;
316  }
317  }
318  print_to_screen(out.str(), command);
319  }
320 
323  {
324  std::stringstream out;
325  // Iterate over all backends to see if command matches one of them
326  for (const auto &backend : backend_versions)
327  {
328  if (command == backend.first)
329  {
330  bool has_classloader = false;
331  out << "Information for backend " << backend.first << "." << std::endl << std::endl;
332 
333  // Loop over all registered versions of this backend
334  for (const auto &version : backend.second)
335  {
336  bool who_cares;
337  const str path = backendData->corrected_path(backend.first, version); // Save the path of this backend
338  const str status = backend_status(backend.first, version, who_cares); // Save the status of this backend
339  out << "Version: " << version << std::endl;
340  out << "Path to library: " << path << std::endl;
341  out << "Library status: " << status << std::endl;
342 
343  table_formatter back_table(" Function/Variable", "Capability", "Type", "Status");
344  back_table.capitalize_title();
345  back_table.default_widths(27, 35, 40, 40);
346  back_table.padding(1);
347  back_table.top_line(true);
348  back_table.bottom_line(true);
349  // Loop over all the backend functions and variables
350  for (const auto &functor : backendFunctorList)
351  {
352  if ((functor->origin() == backend.first) and (functor->version() == version))
353  {
354  const str f = functor->name();
355  const str c = functor->capability();
356  const str t = functor->type();
357  const int s = functor->status();
358  back_table << (" " + f) << c << t;
359  if (s == -5)
360  back_table.red() << "Mathematica absent";
361  else if (s == -2)
362  back_table.red() << "Function absent";
363  else if (s == -1)
364  back_table.red() << "Backend absent";
365  else if (s >= 0)
366  back_table.green() << "Available";
367  else
368  back_table << "";
369  }
370  }
371  if (back_table.rows() > 0) out << back_table.str();
372  table_formatter class_table(" Class", "Constructor overload", "Status");
373  class_table.capitalize_title();
374  class_table.default_widths(46, 60, 60);
375  class_table.padding(1);
376  class_table.top_line(true);
377  class_table.bottom_line(true);
378  // If this version has classes to offer, print out info on them too
379  if (backendData->classloader.at(backend.first + version))
380  {
381  std::set<str> classes;
382  if (backendData->classes.find(backend.first + version) != backendData->classes.end()) classes = backendData->classes.at(backend.first + version);
383  has_classloader = true;
384  // Loop over the classes
385  for (const auto &class_ : classes) // class is a C++ keyword, so use class_ here which allows the same readability.
386  {
387  const std::set<str> ctors = backendData->factory_args.at(backend.first + version + class_);
388  // Loop over the constructors in each class
389  for (const auto &ctor : ctors)
390  {
391  str args = ctor;
392  boost::replace_all(args, "my_ns::", "");
393  const str ss = backendData->constructor_status.at(backend.first + version + class_ + args);
394  const str firstentry = (&ctor == std::addressof(*ctors.begin()) ? class_ : "");
395  class_table << (" " + firstentry) << args;
396  if (ss == "OK")
397  class_table.green() << status;
398  else
399  class_table.red() << status;
400  }
401  }
402  }
403  if (class_table.rows() > 0) out << class_table.str();
404  }
405  // Tell the user what the default version is for classes of this backend (if there are any).
406  if (has_classloader)
407  {
408  const std::map<str, str> defs = backendData->default_safe_versions;
409  const str my_def = (defs.find(backend.first) != defs.end() ? backendData->version_from_safe_version(backend.first, defs.at(backend.first)) : "none");
410  out << std::endl << "Default version for loaded classes: " << my_def << std::endl << std::endl;
411  }
412  break;
413  }
414  }
415  print_to_screen(out.str(), command);
416  }
417 
420  {
421  std::stringstream out;
422  // Iterate over all models to see if command matches one of them
423  for (const auto &functor : primaryModelFunctorList)
424  {
425  const str model = functor->origin();
426  if (command == model)
427  {
428  out << "Information for model " << model << "." << endl << endl;
429 
430  // Retrieve info on this capability from the database file
431  const model_info mod = get_model_info(model);
432 
433  // Need copies of lineage and descendant vectors with self-reference removed
434  std::vector<str> lin_X = mod.lineage;
435  std::vector<str> des_X = mod.descendants;
436 
437  // Erase element matching name
438  lin_X.erase(std::remove(lin_X.begin(), lin_X.end(), mod.name), lin_X.end());
439  des_X.erase(std::remove(des_X.begin(), des_X.end(), mod.name), des_X.end());
440 
441  out << " Parent Model: " << mod.parent << std::endl;
442  out << " Number of parameters: " << mod.nparams << std::endl;
443  out << " Parameter names:" << mod.parameters << std::endl;
444  out << " 'Ancestor' models:" << lin_X << std::endl;
445  out << " 'Descendant' models:" << des_X << std::endl;
446  out << " Description: " << endl << mod.description << std::endl;
447 
448  break;
449  }
450  }
451  print_to_screen(out.str(), command);
452  }
453 
456  {
457  std::stringstream out;
458  // Iterate over all capabilities to see if command matches one of them
459  for (const auto &capability : capabilities)
460  {
461  if (command == capability)
462  {
463  out << "Information for capability " << capability << "." << std::endl << std::endl;
464 
465  // Retrieve info on this capability from the database file
466  const capability_info cap = get_capability_info(capability);
467  std::vector<std::pair<str, std::map<str, std::set<std::pair<str, str>>>>> origins;
468  origins.push_back(std::pair<str, std::map<str, std::set<std::pair<str, str>>>>("modules", cap.modset));
469  origins.push_back(std::pair<str, std::map<str, std::set<std::pair<str, str>>>>("backends", cap.beset));
470  // Loop over {modules, backends}
471  for (const auto &origin : origins)
472  {
473  if (not origin.second.empty())
474  {
475  out << " Available in " << origin.first << ": " << std::endl;
476  // Loop over modules or backends
477  for (const auto &module_or_backend : origin.second)
478  {
479  out << " " << module_or_backend.first << ": " << std::endl;
480  // Loop over matching module/backend functions
481  for (const auto &function : module_or_backend.second)
482  {
483  // Spit out: function name [function type]
484  out << " function " << function.first << " [type " << function.second << "]" << std::endl;
485  }
486  }
487  out << std::endl;
488  }
489  }
490  out << " Description: " << std::endl << cap.description << std::endl;
491  break;
492  }
493  }
494  print_to_screen(out.str(), command);
495  }
496 
499  {
500  const std::string output = Scanner::Plugins::plugin_info().print_plugin("scanner", command);
501  print_to_screen(output, command);
502  }
503 
506  {
507  const std::string output = Scanner::Plugins::plugin_info().print_plugin("objective", command);
508  print_to_screen(output, command);
509  }
510 
511 } // namespace Gambit
void ff_capability_diagnostic(const str &)
Free-form capability diagnostic function.
str version() const
Getter for the version of the wrapped function&#39;s origin (module or backend)
Definition: functors.cpp:123
Define overloadings of the stream operator for various containers.
std::map< str, std::set< str > > backend_versions
Map from backend names to a list of all registered versions of the backend.
Definition: core.hpp:56
table_formatter & green(int i=-1, int j=-1)
table_formatter & red(int i=-1, int j=-1)
void new_titles(const T &... in)
virtual std::set< sspair > backendreqs()
Getter for listing all backend requirements.
Definition: functors.cpp:232
std::map< str, std::set< std::pair< str, str > > > modset
Set of modules and module functions in which capability is used, along with corresponding result type...
str backend_status(const str &, const str &, bool &)
Compute the status of a given backend.
Definition: core.cpp:530
int nparams
Number of parameters ( parameters.size() )
void capability_diagnostic()
Basic capability diagnostic function.
std::vector< str > parameters
Parameter names.
virtual str loopManagerCapability()
Getter for revealing the required capability of the wrapped function&#39;s loop manager.
Definition: functors.cpp:190
Helper struct to carry around model information.
void ff_prior_diagnostic(const str &)
capability_info get_capability_info(const str &) const
Get the description (and other info) of the named item from the capability database.
Definition: core.cpp:491
Function wrapper (functor) base class.
Definition: functors.hpp:87
void ff_module_diagnostic(const str &)
Free-form diagnostic functions.
void model_diagnostic()
Basic model diagnostic function.
model_info get_model_info(const str &) const
Get the description (and other info) of the named item from the model database.
Definition: core.cpp:510
void ff_model_diagnostic(const str &)
Free-form model diagnostic function.
void backend_diagnostic()
Basic backend diagnostic function.
Definition: diagnostics.cpp:84
str get_parent(const str &) const
Retrieve the parent model for a given model.
Definition: models.cpp:244
str origin() const
Getter for the wrapped function&#39;s origin (module or backend name)
Definition: functors.cpp:121
fVec functorList
List of all declared module functors.
Definition: core.hpp:65
std::set< str > capabilities
List of all declared capabilities.
Definition: core.hpp:59
table_formatter & newline(int j=-1)
Utility Functions for the Gambit Scanner.
General small utility functions.
table_formatter & no_newline(int j=-1)
void ff_scanner_diagnostic(const str &)
Free-form scanner diagnostic function.
str name() const
Getter for the wrapped function&#39;s name.
Definition: functors.cpp:115
virtual bool canBeLoopManager()
Getter for revealing whether this is permitted to be a manager functor.
Definition: functors.cpp:183
virtual std::set< sspair > dependencies()
Getter for listing currently activated dependencies.
Definition: functors.cpp:218
std::set< str > modules
Set of all declared modules.
Definition: core.hpp:53
void ff_test_function_diagnostic(const str &)
Free-form test function diagnostic function.
pmfVec primaryModelFunctorList
List of all declared primary model functors.
Definition: core.hpp:74
std::map< str, std::set< std::pair< str, str > > > beset
Set of backends and backend functions in which capability is used, along with corresponding type sign...
GAMBIT Core driver class.
str type() const
Getter for the wrapped function&#39;s reported return type.
Definition: functors.cpp:119
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
Model graph declarations.
void test_function_diagnostic()
Basic test function diagnostic function.
str capability() const
Getter for the wrapped function&#39;s reported capability.
Definition: functors.cpp:117
Helper struct to carry around capability information.
void scanner_diagnostic()
Basic scanner diagnostic function.
void default_widths(const T &... in)
Utility Functions for the Gambit Scanner.
void ff_backend_diagnostic(const str &)
Free-form backend diagnostic function.
EXPORT_SYMBOLS const str & runtime_scratch()
Return the path to the run-specific scratch directory Don&#39;t call this from a destructor, as the internal static str may have already been destroyed.
const Models::ModelFunctorClaw * modelInfo
Internal model claw pointer.
Definition: core.hpp:47
std::vector< str > descendants
All children and later descendants.
std::vector< str > lineage
Parent and all ancestor models.
void module_diagnostic()
Basic diagnostic functions.
Definition: diagnostics.cpp:41
str description
Full description of capability.
Loader singleton class for scanner plugins.
EXPORT_SYMBOLS pluginInfo plugin_info
Access Functor for plugin info.
int status() const
Getter for the wrapped function current status: -4 = required backend absent (backend ini functions) ...
Definition: functors.cpp:134
fVec backendFunctorList
List of all declared backend functors.
Definition: core.hpp:71
str parent
Parent model name.
TODO: see if we can use this one:
Definition: Analysis.hpp:33
str description
Full description of capability.
Model hierarchy tree class.
Definition: modelgraph.hpp:36
const Backends::backend_info * backendData
Internal backend info pointer.
Definition: core.hpp:50
void print_to_screen(const std::string &file_in, const std::string &name)