MachineIntelligenceCore:Toolchain
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ParameterServer.cpp
Go to the documentation of this file.
1 
24 
25 #include <boost/property_tree/json_parser.hpp>
26 
27 namespace mic {
28 namespace configuration {
29 
30 // Initialize application instance - as NULL.
31 boost::atomic<ParameterServer*> ParameterServer::instance_(NULL);
32 
33 // Initilize mutex.
35 
36 using boost::property_tree::ptree;
37 
38 namespace po = boost::program_options;
39 namespace pt = boost::property_tree;
40 
41 template<class Ptree>
42 inline const Ptree & empty_ptree()
43 {
44  static Ptree pt;
45  return pt;
46 }
47 
49  // Try to load the instance - first check.
50  ParameterServer* tmp = instance_.load(boost::memory_order_consume);
51  // If instance does not exist.
52  if (!tmp) {
53  // Enter critical section.
54  boost::mutex::scoped_lock guard(instantiation_mutex);
55  // Try to load the instance - second check.
56  tmp = instance_.load(boost::memory_order_consume);
57  // If still does not exist - create new instance.
58  if (!tmp) {
59  tmp = new ParameterServer;
60  instance_.store(tmp, boost::memory_order_release);
61  }//: if
62  // Exit critical section.
63  }//: if
64  // Return instance.
65  return tmp;
66 }
67 
69 : program_options("Allowed options")
70 {
71  // TODO Auto-generated constructor stub
72 }
73 
74 void ParameterServer::print(boost::property_tree::ptree const& pt_)
75 {
76  LOG(LDEBUG)<< "Properties loaded from config file (raw):";
77  for (ptree::const_iterator it = pt_.begin(); it != pt_.end(); ++it) {
78  LOG(LDEBUG) <<it->first << ": " << it->second.get_value<std::string>() << std::endl;
79  print(it->second);
80  }
81 }
82 
83 
84 const boost::property_tree::ptree & ParameterServer::returnNode(std::string node_name_)
85 {
86  // Try to find the node.
87  for (ptree::const_iterator it = config_tree.begin(); it != config_tree.end(); ++it) {
88  if (it->first == node_name_) {
89  LOG(LINFO)<< "Node \"" << node_name_ << "\" has been found in config file";
90  return it->second;
91  }//: if
92  }//: for
93 
94  // Return empty ptree otherwise.
95  LOG(LWARNING)<< "Node " << node_name_ << " not found in config file";
96  return empty_ptree<ptree>();
97 }
98 
99 
100 void ParameterServer::parseApplicationParameters(int argc, char* argv[]) {
101  // Extract application (binary file) name.
102  std::string tmp = std::string(argv[0]);
103  application_name = tmp.substr(tmp.find_last_of("/\\")+1);
104 
105  // Config filenames.
106  std::string default_config_name = application_name + ".json";
107 
108  std::string existing_config_name;
109 
110  std::string new_config_name = application_name + ".json";
111 
112  // Logger level.
113  int log_lvl;
114 
115  // Declare the supported command-line options
116  // NOTE: Program options are already created (in constructor) and may have been extended by applications.
117  program_options.add_options()
118  ("help,h", "Display (h)elp message")
119  ("load-config,l", po::value<std::string>(&existing_config_name)->default_value(default_config_name.c_str()), "(L)oad configuration from given JSON file")
120  ("create-config,c", "(C)reate default configuration JSON file")
121  ("set-logger-level,s", po::value<int>(&log_lvl)->default_value(3), "(S)et logger severity level")
122  ;
123 
124  // Variables map.
125  po::variables_map vm;
126 
127  // Try to parse the parameters.
128  try {
129  po::store(po::parse_command_line(argc, argv, program_options), vm);
130  po::notify(vm);
131  }
132  catch (const po::error & u) {
133  std::cout << u.what() << "\n";
134  exit (0);
135  }
136 
137 
138  if (vm.count("help")) {
139  std::cout << program_options << "\n";
140  exit (0);
141  }
142 
143  // Set logger severity level.
144  LOGGER->setSeverityLevel((mic::logger::Severity_t)log_lvl);
145 
146  if (vm.count("create-config")) {
147  std::cout << "Creating JSON file " << new_config_name << " with default configuration \n";
148 
149  std::ofstream cfg(new_config_name.c_str());
150 
151  cfg << "{\n"
152  " \"app_state\": {\n"
153  " \"application_sleep_interval\": \"1000\"\n"
154  " },\n"
155  " \"";
156  cfg << std::string(argv[0]).erase(0,2);
157  cfg << "\": {\n"
158  " \"learning_iterations_to_test_ratio\": \"50\",\n"
159  " \"number_of_averaged_test_measures\": \"5\"\n"
160  " }\n"
161  "}";
162 
163  cfg.close();
164 
165  exit (0);
166  }//: create config
167 
168  try {
169  read_json(existing_config_name, config_tree);
170 
171  // Debug print config tree.
172  LOG(LSTATUS) << "Configuration file \"" << existing_config_name + "\" was loaded properly";
174 
175  }
176  catch(boost::property_tree::json_parser_error&) {
177  LOG(LERROR) << "Configuration file \"" << existing_config_name + "\" was not found or invalid";
178  LOG(LINFO) << "Quick fixes:";
179  LOG(LINFO) << " specify config file name with -l switch";
180  LOG(LINFO) << " create default configuration using -c switch";
181 
182  exit (0);
183  }//: catch
184 
185 }
186 
187 
189  if (pt_ != NULL) {
190  LOG(LDEBUG) <<"Registering property tree " << pt_->getNodeName();
191  // Register the property tree. TODO: add checking whether another property with that name existed earlier...
192  property_trees_registry[pt_->getNodeName()] = pt_;
193  }//: if
194 }
195 
197  // For each "main" node in the loaded configuration.
198  for (boost::property_tree::ptree::const_iterator cfg_it = config_tree.begin(); cfg_it != config_tree.end(); ++cfg_it) {
199 
200  // Find property tree with given id.
201  id_pt_it_t reg_it = property_trees_registry.find(cfg_it->first);
202  if (reg_it != property_trees_registry.end()) {
203  reg_it->second->loadPropertiesFromConfigNode(cfg_it->second);
204  } else {
205  LOG(LERROR) <<"Object \"" << cfg_it->first << "\" appearing in the loaded config file was not found in the property tree registry";
206  }//: else
207 
208  }//: for
209 
210  LOG(LINFO) << "Configuration completed";
211  LOG(LSTATUS) << "List of application properties:";
212 
213  // For each registered property tree.
214  for (id_pt_it_t reg_it = property_trees_registry.begin(); reg_it != property_trees_registry.end(); ++reg_it) {
215  reg_it->second->printPropertiesWithValues();
216  }//: for
217 
218  LOG(LINFO) << "Property-dependent variables initialized";
219 }
220 
222  LOG(LSTATUS) << "Initializing property-dependent variables";
223 
224  // For each registered property tree.
225  for (id_pt_it_t reg_it = property_trees_registry.begin(); reg_it != property_trees_registry.end(); ++reg_it) {
226 
227  // Find property tree with given id.
228  reg_it->second->initializePropertyDependentVariables();
229 
230  }//: for
231 
232  LOG(LINFO) << "Property-dependent variables initialized";
233 }
234 
235 
236 boost::program_options::options_description &ParameterServer::getProgramOptions() {
237  return program_options;
238 }
239 
240 const boost::program_options::variables_map &ParameterServer::getProgramArguments() {
241  return program_arguments;
242 }
243 
244 } /* namespace configuration */
245 } /* namespace mic */
static ParameterServer * getInstance()
void parseApplicationParameters(int argc, char *argv[])
Severity_t
Message severity level.
Definition: LoggerAux.hpp:35
#define LDEBUG
Definition: LoggerAux.hpp:53
Parent class for all classes possessing properties. Contains methods useful for their management...
Contains declaration of parameter server singleton along with some auxiliary typedefs.
#define LERROR
Definition: LoggerAux.hpp:58
const Ptree & empty_ptree()
#define LINFO
Definition: LoggerAux.hpp:55
std::string application_name
Name of the executed binary file.
const boost::property_tree::ptree & returnNode(std::string node_name_)
void print(boost::property_tree::ptree const &pt)
#define LWARNING
Definition: LoggerAux.hpp:57
std::string getNodeName() const
Server of application parameters - defined in the form of a singleton, with double-checked locking pa...
std::map< std::string, mic::configuration::PropertyTree * >::iterator id_pt_it_t
Type used during iterating/searching for property trees in registry.
static boost::atomic< ParameterServer * > instance_
boost::program_options::options_description program_options
boost::program_options::variables_map program_arguments
boost::property_tree::ptree config_tree
#define LSTATUS
Definition: LoggerAux.hpp:56
boost::program_options::options_description & getProgramOptions()
void registerPropertyTree(mic::configuration::PropertyTree *pt_)
#define LOG(level)
Macro for message printing.
Definition: Log.hpp:39
std::map< std::string, mic::configuration::PropertyTree * > property_trees_registry
#define LOGGER
Macro returning logger instance.
Definition: Log.hpp:34
const boost::program_options::variables_map & getProgramArguments()