gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
scan.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
26 
31 
32 namespace Gambit
33 {
34 
35  namespace Scanner
36  {
37 
38  inline YAML::Node combineNodes(const std::map<std::string, YAML::Node> &nodesMap, const YAML::Node &node)
39  {
40  YAML::Node outNode = node;
41 
42  for (auto it = nodesMap.begin(), end = nodesMap.end(); it != end; it++)
43  {
44  outNode[it->first] = it->second;
45  }
46 
47  return outNode;
48  }
49 
50  Scan_Manager::Scan_Manager (const YAML::Node &main_node, printer_interface *printerInterface, const Factory_Base *factoryIn)
51  : printerInterface(printerInterface), has_local_factory(false)
52  {
53  options = main_node["Scanner"];
54 
56 
57  if (options.hasKey("use_objectives"))
58  {
59  std::map< std::string, std::vector<std::pair<std::string, std::string>> > names;
60  std::map< std::string, YAML::Node > nodes;
61  std::vector <std::string> plugs = get_yaml_vector<std::string>(options.getNode("use_objectives"));
62 
63  for (auto it = plugs.begin(), end = plugs.end(); it != end; it++)
64  {
65  if (options.hasKey("objectives") && options.hasKey("objectives", *it))
66  {
67  std::string plugin_name;
68  if (options.hasKey("objectives", *it, "purpose") && options.hasKey("objectives", *it, "plugin"))
69  {
70  std::vector <std::string> purposes = get_yaml_vector<std::string>(options.getNode("objectives", *it, "purpose"));
71  plugin_name = options.getValue<std::string>("objectives", *it, "plugin");
72  for (auto it2 = purposes.begin(), end = purposes.end(); it2 != end; it2++)
73  names[*it2].push_back(std::pair<std::string, std::string>(*it, plugin_name));
74  }
75  else
76  {
77  scan_err << "Must specify a plugin and a purpose under the plugin tag \"" << *it << "\"." << scan_end;
78  }
79 
80  if (options.hasKey("objectives", *it, "parameters"))
81  {
82  if (options.hasKey("parameters") && options.hasKey("parameters", *it))
83  {
84  scan_err << "Plugin \"" << *it << "\"'s parameters are defined in "
85  << "both the \"parameters\" section and the \"plugins\" "
86  << "section in the inifile." << scan_end;
87  }
88 
89  nodes[plugin_name] = options.getNode("objectives", *it, "parameters");
90  //nodes[*it] = options.getNode("objectives", *it, "parameters");
91  }
92  }
93  else
94  {
95  scan_err << "Plugin \"" << *it << "\" of type \"" << "objective" << "\" is not defined under the \"Scanner\""
96  << " subsection in the inifile" << scan_end;
97  }
98  }
99 
100  if (names.size() > 0)
101  {
102  YAML::Node paramNode;
103 
104  if (nodes.size() > 0)
105  {
106  paramNode = combineNodes(nodes, main_node["Parameters"]);
107  }
108  else
109  {
110  paramNode = main_node["Parameters"];
111  }
112 
113  prior = new Gambit::Priors::CompositePrior(paramNode, main_node["Priors"]);
115  Plugins::plugin_info.printer_prior(*printerInterface, *prior);
116  has_local_factory = true;
117  }
118  else
119  {
120  prior = new Gambit::Priors::CompositePrior(main_node["Parameters"], main_node["Priors"]);
121  factory = factoryIn;
122  Plugins::plugin_info.printer_prior(*printerInterface, *prior);
123  }
124  }
125  else
126  {
127  prior = new Gambit::Priors::CompositePrior(main_node["Parameters"], main_node["Priors"]);
128  factory = factoryIn;
129  Plugins::plugin_info.printer_prior(*printerInterface, *prior);
130  }
131  }
132 
134  {
135  std::vector<std::string> pluginNames;
136  if (options.hasKey("use_scanner") && options.getNode("use_scanner").IsScalar())
137  {
138  pluginNames = get_yaml_vector<std::string>(options.getNode("use_scanner"));
139  }
140  else
141  {
142  scan_err << "\"use_scanner:\" input value not usable in the inifile." << scan_end;
143  }
144 
145  // Before allowing scan to begin, add a barrier so that some don't start without others
146  // Otherwise, attempting to shut down with only some processes begun will screw up the
147  // output.
148  #ifdef WITH_MPI
149  GMPI::Comm comm;
150  comm.dup(MPI_COMM_WORLD,"ScanRunComm"); // duplicates MPI_COMM_WORLD
151  int rank = comm.Get_rank();
152  if(rank==0)
153  {
154  cout << "ScannerBit is waiting for all MPI processes to join the scan..." << endl;
155  }
156  comm.Barrier();
157  if(rank==0)
158  {
159  cout << " All processes ready!" << endl;
160  }
161  #else
162  int rank = 0;
163  #endif
164 
165  unsigned int dim = prior->size();
166 
167  for(auto &&pluginName : pluginNames)
168  {
169  Plugins::Plugin_Interface<int ()> plugin_interface("scanner", pluginName, dim, *factory);
170  plugin_interface();
171  }
172 
173  // Check shutdown flags across all processes (COLLECTIVE OPERATION)
174  #ifdef WITH_MPI
175  if(rank==0) cout << "ScannerBit is waiting for all MPI processes to report their shutdown condition..." << endl;
176  const MPI_Datatype datatype = GMPI::get_mpi_data_type<int>::type(); // datatype for ints
178  std::vector<int> all_vals(comm.Get_size(),0);
179  MPI_Allgather(
180  &sendbuf, /* send buffer */
181  1, /* send count */
182  datatype, /* send datatype */
183  &all_vals[0], /* recv buffer */
184  1, /* recv count */
185  datatype, /* recv datatype */
186  *(comm.get_boundcomm()) /* communicator */
187  );
188  for(auto it=all_vals.begin(); it!=all_vals.end(); ++it)
189  {
190  if(*it!=0)
191  {
192  // Some process is shutting down early, therefore we should all use the early shutdown mode
194  break;
195  }
196  }
197  #endif
198 
199  if(Plugins::plugin_info.early_shutdown_in_progress())
200  {
201  if (rank == 0) cout << "ScannerBit has received a shutdown signal and will terminate early. Finalising resume data..." << endl;
202  printerInterface->finalise(true); // abnormal (early) termination
203  }
204  else
205  {
207  }
208 
209  return 0;
210  }
211 
213  {
214  if (has_local_factory)
215  {
216  delete factory;
217  }
218 
219  delete prior;
220  }
221  }
222 }
Scan_Manager(const YAML::Node &node, printer_interface *, const Factory_Base *factory=0)
Definition: scan.cpp:50
Interface details for scanner plugins.
Printers::PrinterManager * printerInterface
Factory class to make objectives using objective plugins.
const Factory_Base * factory
Definition: scan.hpp:42
Pure Base class of a plugin Factory function.
virtual void finalise(bool abnormal=false)=0
Instruct printers that scan has finished and to perform cleanup.
bool hasKey(const args &... keys) const
Getters for key/value pairs (which is all the options node should contain)
void printer_prior(printer_interface &, Priors::BasePrior &)
TYPE getValue(const args &... keys) const
YAML::Node combineNodes(const std::map< std::string, YAML::Node > &nodesMap, const YAML::Node &node)
Definition: scan.cpp:38
unsigned int size() const
Definition: base_prior.hpp:77
#define scan_err
Defined to macros to output errors in the form: scan_err << "error" << scan_end; scan_warn << "warnin...
Scanner method implementations.
Interface for a ScannerBit plugin.
test functions implementations.
void iniFile(const Options &)
Enter plugin inifile.
A simple C++ wrapper for the MPI C bindings.
Priors::CompositePrior * prior
Definition: scan.hpp:44
#define scan_end
std::vector< std::string > getParameters() const
Definition: base_prior.hpp:83
Manager class for creating printer objects.
EXPORT_SYMBOLS pluginInfo plugin_info
Access Functor for plugin info.
TODO: see if we can use this one:
Definition: Analysis.hpp:33
YAML::Node getNode(const args &... keys) const
Retrieve raw YAML node.
printer_interface * printerInterface
Definition: scan.hpp:45
Special "build-a-prior" class This is the class to use for setting simple 1D priors (from the library...
Definition: composite.hpp:47