file src/scan.cpp
[No description available] More…
Namespaces
Name |
---|
Gambit TODO: see if we can use this one: |
Gambit::Scanner |
Detailed Description
Author:
- Christoph Weniger (c.weniger@uva.nl)
- Gregory Martinez (gregory.david.martinez@gmail.com)
- Pat Scott (patscott@physics.mcgill.ca)
Date:
- 2013 May, June, July
- 2013 July, Aug
- 2014 Feb
- 2013 Aug
- 2014 Mar, Dec
Scanner factory method implementations.
Authors (add name and date if you modify):
Source code
// GAMBIT: Global and Modular BSM Inference Tool
// *********************************************
/// \file
///
/// Scanner factory method implementations.
///
/// *********************************************
///
/// Authors (add name and date if you modify):
///
/// \author Christoph Weniger
/// (c.weniger@uva.nl)
/// \date 2013 May, June, July
///
/// \author Gregory Martinez
/// (gregory.david.martinez@gmail.com)
/// \date 2013 July, Aug
/// \date 2014 Feb
///
/// \author Pat Scott
/// (patscott@physics.mcgill.ca)
/// \date 2013 Aug
/// \date 2014 Mar, Dec
///
/// *********************************************
#include "gambit/ScannerBit/scan.hpp"
#include "gambit/ScannerBit/plugin_interface.hpp"
#include "gambit/ScannerBit/plugin_factory.hpp"
#include "gambit/Utils/mpiwrapper.hpp"
namespace Gambit
{
namespace Scanner
{
inline YAML::Node combineNodes(const std::map<std::string, YAML::Node> &nodesMap, const YAML::Node &node)
{
YAML::Node outNode = node;
for (auto it = nodesMap.begin(), end = nodesMap.end(); it != end; it++)
{
outNode[it->first] = it->second;
}
return outNode;
}
Scan_Manager::Scan_Manager (const YAML::Node &main_node, printer_interface *printerInterface, const Factory_Base *factoryIn)
: printerInterface(printerInterface), has_local_factory(false)
{
options = main_node["Scanner"];
Plugins::plugin_info.iniFile(options);
if (options.hasKey("use_objectives"))
{
std::map< std::string, std::vector<std::pair<std::string, std::string>> > names;
std::map< std::string, YAML::Node > nodes;
std::vector <std::string> plugs = get_yaml_vector<std::string>(options.getNode("use_objectives"));
for (auto it = plugs.begin(), end = plugs.end(); it != end; it++)
{
if (options.hasKey("objectives") && options.hasKey("objectives", *it))
{
std::string plugin_name;
if (options.hasKey("objectives", *it, "purpose") && (options.hasKey("objectives", *it, "plugin" )))
{
std::vector <std::string> purposes = get_yaml_vector<std::string>(options.getNode("objectives", *it, "purpose"));
plugin_name = options.getValue<std::string>("objectives", *it, "plugin");
for (auto it2 = purposes.begin(), end = purposes.end(); it2 != end; it2++)
names[*it2].push_back(std::pair<std::string, std::string>(*it, plugin_name));
}
else
{
scan_err << "Must specify a plugin and a purpose under the plugin tag \"" << *it << "\"." << scan_end;
}
if (options.hasKey("objectives", *it, "parameters"))
{
if (options.hasKey("parameters") && options.hasKey("parameters", *it))
{
scan_err << "Plugin \"" << *it << "\"'s parameters are defined in "
<< "both the \"parameters\" section and the \"plugins\" "
<< "section in the inifile." << scan_end;
}
nodes[plugin_name] = options.getNode("objectives", *it, "parameters");
//nodes[*it] = options.getNode("objectives", *it, "parameters");
}
}
else
{
scan_err << "Plugin \"" << *it << "\" of type \"" << "objective" << "\" is not defined under the \"Scanner\""
<< " subsection in the inifile" << scan_end;
}
}
if (names.size() > 0)
{
YAML::Node paramNode;
if (nodes.size() > 0)
{
paramNode = combineNodes(nodes, main_node["Parameters"]);
}
else
{
paramNode = main_node["Parameters"];
}
prior = new Gambit::Priors::CompositePrior(paramNode, main_node["Priors"]);
factory = new Plugin_Function_Factory(prior->getParameters(), names);
Plugins::plugin_info.printer_prior(*printerInterface, *prior);
has_local_factory = true;
}
else
{
prior = new Gambit::Priors::CompositePrior(main_node["Parameters"], main_node["Priors"]);
factory = factoryIn;
Plugins::plugin_info.printer_prior(*printerInterface, *prior);
}
}
else
{
prior = new Gambit::Priors::CompositePrior(main_node["Parameters"], main_node["Priors"]);
factory = factoryIn;
Plugins::plugin_info.printer_prior(*printerInterface, *prior);
}
}
int Scan_Manager::Run()
{
std::vector<std::string> pluginNames;
if (options.hasKey("use_scanner") && options.getNode("use_scanner").IsScalar())
{
pluginNames = get_yaml_vector<std::string>(options.getNode("use_scanner"));
}
else
{
scan_err << "\"use_scanner:\" input value not usable in the inifile." << scan_end;
}
// Before allowing scan to begin, add a barrier so that some don't start without others
// Otherwise, attempting to shut down with only some processes begun will screw up the
// output.
#ifdef WITH_MPI
GMPI::Comm comm;
comm.dup(MPI_COMM_WORLD,"ScanRunComm"); // duplicates MPI_COMM_WORLD
int rank = comm.Get_rank();
if(rank==0)
{
cout << "ScannerBit is waiting for all MPI processes to join the scan..." << endl;
}
comm.Barrier();
if(rank==0)
{
cout << " All processes ready!" << endl;
}
#else
int rank = 0;
#endif
unsigned int dim = prior->size();
for(auto &&pluginName : pluginNames)
{
Plugins::Plugin_Interface<int ()> plugin_interface("scanner", pluginName, dim, *factory);
plugin_interface();
}
// Check shutdown flags across all processes (COLLECTIVE OPERATION)
#ifdef WITH_MPI
if(rank==0) cout << "ScannerBit is waiting for all MPI processes to report their shutdown condition..." << endl;
const MPI_Datatype datatype = GMPI::get_mpi_data_type<int>::type(); // datatype for ints
int sendbuf = Plugins::plugin_info.early_shutdown_in_progress();
std::vector<int> all_vals(comm.Get_size(),0);
MPI_Allgather(
&sendbuf, /* send buffer */
1, /* send count */
datatype, /* send datatype */
&all_vals[0], /* recv buffer */
1, /* recv count */
datatype, /* recv datatype */
*(comm.get_boundcomm()) /* communicator */
);
for(auto it=all_vals.begin(); it!=all_vals.end(); ++it)
{
if(*it!=0)
{
// Some process is shutting down early, therefore we should all use the early shutdown mode
Plugins::plugin_info.set_early_shutdown_in_progress();
break;
}
}
#endif
if(Plugins::plugin_info.early_shutdown_in_progress())
{
if (rank == 0) cout << "ScannerBit has received a shutdown signal and will terminate early. Finalising resume data..." << endl;
printerInterface->finalise(true); // abnormal (early) termination
}
else
{
printerInterface->finalise();
}
return 0;
}
Scan_Manager::~Scan_Manager()
{
if (has_local_factory && factory != 0)
{
delete factory;
}
if (prior != 0)
delete prior;
}
}
}
Updated on 2024-07-18 at 13:53:33 +0000