BioDynaMo  v1.05.117-b1949764
param.cc
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #include <TBufferJSON.h>
16 #include <json.hpp>
17 
18 #include <utility>
19 #include <vector>
20 
22 #include "core/param/param.h"
23 #include "core/util/cpptoml.h"
24 #include "core/util/log.h"
25 
26 using nlohmann::json;
27 
28 namespace bdm {
29 
30 const bdm::ParamGroupUid bdm::OptimizationParam::kUid =
32 
33 std::unordered_map<ParamGroupUid, std::unique_ptr<ParamGroup>>
35 
36 // -----------------------------------------------------------------------------
38  registered_groups_[param->GetUid()] = std::unique_ptr<ParamGroup>(param);
39 }
40 
41 // -----------------------------------------------------------------------------
44  for (auto& el : registered_groups_) {
45  groups_[el.first] = el.second->NewCopy();
46  }
47 }
48 
49 // -----------------------------------------------------------------------------
51  for (auto& el : groups_) {
52  delete el.second;
53  }
54 }
55 
56 // -----------------------------------------------------------------------------
57 void Param::Restore(Param&& other) {
58  for (auto& el : groups_) {
59  delete el.second;
60  }
61  *this = other;
62  other.groups_.clear();
63 }
64 
65 Param::Param(const Param& other) {
66  *this = other;
67  for (auto el : other.groups_) {
68  this->groups_[el.first] = el.second->NewCopy();
69  }
70 }
71 
72 // -----------------------------------------------------------------------------
73 json FlattenGroups(const json& j_document) {
74  json j_copy = j_document;
75  j_copy.erase("groups_");
76 
77  json j_new;
78  j_new["bdm::Param"] = j_copy;
79 
80  // iterator over all group parameters
81  auto j_groups = j_document["groups_"];
82  for (json::iterator it = j_groups.begin(); it != j_groups.end(); ++it) {
83  j_new[(*it)["second"]["_typename"].get<std::string>()] = (*it)["second"];
84  }
85  return j_new;
86 }
87 
88 // -----------------------------------------------------------------------------
89 json UnflattenGroups(const json& j_flattened, const json& j_original) {
90  json j_return = j_flattened["bdm::Param"];
91  j_return["groups_"] = {};
92  auto& j_groups = j_return["groups_"];
93 
94  auto j_original_groups = j_original["groups_"];
95  for (json::iterator it = j_original_groups.begin();
96  it != j_original_groups.end(); ++it) {
97  json j_param_group;
98  j_param_group["$pair"] = (*it)["$pair"];
99  j_param_group["first"] = (*it)["first"];
100  j_param_group["second"] =
101  j_flattened[(*it)["second"]["_typename"].get<std::string>()];
102  j_groups.push_back(j_param_group);
103  }
104  return j_return;
105 }
106 
107 // -----------------------------------------------------------------------------
108 std::string Param::ToJsonString() const {
109  // If you segfault here, try running the unit tests to find the root cause
110  std::string current_json_str(
111  TBufferJSON::ToJSON(this, TBufferJSON::kMapAsObject).Data());
112  // Flatten groups_ to simplify json patches in rfc7386 format.
113  try {
114  json j_document = json::parse(current_json_str);
115  auto j_flattened = FlattenGroups(j_document);
116  return j_flattened.dump(4);
117  } catch (std::exception& e) {
118  Log::Fatal("Param::ToJsonString",
119  Concat("Couldn't parse `Param` parameters.\n", e.what(), "\n",
120  current_json_str));
121  return std::string();
122  }
123 }
124 
125 // -----------------------------------------------------------------------------
126 void Param::MergeJsonPatch(const std::string& patch) {
127  // If you segfault here, try running the unit tests to find the root cause
128  std::string json_str(
129  TBufferJSON::ToJSON(this, TBufferJSON::kMapAsObject).Data());
130  json j_param = json::parse(json_str);
131  auto j_flattened = FlattenGroups(j_param);
132 
133  auto j_patch = json::parse(patch);
134  try {
135  j_flattened.merge_patch(j_patch);
136  } catch (std::exception& e) {
137  Log::Fatal("Param::MergeJsonPatch",
138  Concat("Couldn't merge the given json parameters.\n", e.what(),
139  "\n", j_patch));
140  }
141 
142  auto j_unflattened = UnflattenGroups(j_flattened, j_param);
143  Param* restored = nullptr;
144  TBufferJSON::FromJSON(restored, j_unflattened.dump().c_str());
145  Restore(std::move(*restored));
146 }
147 
148 // -----------------------------------------------------------------------------
149 void AssignThreadSafetyMechanism(const std::shared_ptr<cpptoml::table>& config,
150  Param* param) {
151  const std::string config_key = "simulation.thread_safety_mechanism";
152  if (config->contains_qualified(config_key)) {
153  auto value = config->get_qualified_as<std::string>(config_key);
154  if (!value) {
155  return;
156  }
157  auto str_value = *value;
158  if (str_value == "none") {
159  param->thread_safety_mechanism = Param::ThreadSafetyMechanism::kNone;
160  } else if (str_value == "user-specified") {
161  param->thread_safety_mechanism =
162  Param::ThreadSafetyMechanism::kUserSpecified;
163  } else if (str_value == "automatic") {
164  param->thread_safety_mechanism = Param::ThreadSafetyMechanism::kAutomatic;
165  }
166  }
167 }
168 
169 // -----------------------------------------------------------------------------
170 void AssignMappedDataArrayMode(const std::shared_ptr<cpptoml::table>& config,
171  Param* param) {
172  const std::string config_key = "performance.mapped_data_array_mode";
173  if (config->contains_qualified(config_key)) {
174  auto value = config->get_qualified_as<std::string>(config_key);
175  if (!value) {
176  return;
177  }
178  auto str_value = *value;
179  if (str_value == "zero-copy") {
180  param->mapped_data_array_mode = Param::MappedDataArrayMode::kZeroCopy;
181  } else if (str_value == "cache") {
182  param->mapped_data_array_mode = Param::MappedDataArrayMode::kCache;
183  } else if (str_value == "copy") {
184  param->mapped_data_array_mode = Param::MappedDataArrayMode::kCopy;
185  } else {
186  Log::Fatal(
187  "Param",
188  Concat(
189  "Parameter mapped_data_array_mode was set to an invalid value (",
190  str_value, ")."));
191  }
192  }
193 }
194 
195 // -----------------------------------------------------------------------------
196 void AssignBoundSpaceMode(const std::shared_ptr<cpptoml::table>& config,
197  Param* param) {
198  const std::string config_key = "simulation.bound_space";
199  if (config->contains_qualified(config_key)) {
200  auto value = config->get_qualified_as<std::string>(config_key);
201  if (!value) {
202  return;
203  }
204  auto str_value = *value;
205  if (str_value == "open") {
206  param->mapped_data_array_mode = Param::MappedDataArrayMode::kZeroCopy;
207  } else if (str_value == "closed") {
208  param->mapped_data_array_mode = Param::MappedDataArrayMode::kCache;
209  } else if (str_value == "torus") {
210  param->mapped_data_array_mode = Param::MappedDataArrayMode::kCopy;
211  } else {
212  Log::Fatal("Param",
213  Concat("Parameter bound_space was set to an invalid value (",
214  str_value, ")."));
215  }
216  }
217 }
218 
219 // -----------------------------------------------------------------------------
220 void Param::AssignFromConfig(const std::shared_ptr<cpptoml::table>& config) {
221  // group parameters
222  for (auto& el : groups_) {
223  el.second->AssignFromConfig(config);
224  }
225 
226  // simulation group
227  BDM_ASSIGN_CONFIG_VALUE(random_seed, "simulation.random_seed");
228  BDM_ASSIGN_CONFIG_VALUE(output_dir, "simulation.output_dir");
229  BDM_ASSIGN_CONFIG_VALUE(environment, "simulation.environment");
230  BDM_ASSIGN_CONFIG_VALUE(nanoflann_depth, "simulation.nanoflann_depth");
231  BDM_ASSIGN_CONFIG_VALUE(unibn_bucketsize, "simulation.unibn_bucketsize");
232  BDM_ASSIGN_CONFIG_VALUE(backup_file, "simulation.backup_file");
233  BDM_ASSIGN_CONFIG_VALUE(restore_file, "simulation.restore_file");
234  BDM_ASSIGN_CONFIG_VALUE(backup_interval, "simulation.backup_interval");
235  BDM_ASSIGN_CONFIG_VALUE(simulation_time_step, "simulation.time_step");
237  "simulation.max_displacement");
238  BDM_ASSIGN_CONFIG_VALUE(min_bound, "simulation.min_bound");
239  BDM_ASSIGN_CONFIG_VALUE(max_bound, "simulation.max_bound");
241  "simulation.diffusion_boundary_condition");
242  BDM_ASSIGN_CONFIG_VALUE(diffusion_method, "simulation.diffusion_method");
244  "simulation.calculate_gradients");
245  AssignBoundSpaceMode(config, this);
246  AssignThreadSafetyMechanism(config, this);
247 
248  // visualization group
249  BDM_ASSIGN_CONFIG_VALUE(visualization_engine, "visualization.adaptor");
250  BDM_ASSIGN_CONFIG_VALUE(insitu_visualization, "visualization.insitu");
252  "visualization.pv_insitu_pipeline");
254  "visualization.pv_insitu_pipelinearguments");
255  BDM_ASSIGN_CONFIG_VALUE(root_visualization, "visualization.root");
256  BDM_ASSIGN_CONFIG_VALUE(export_visualization, "visualization.export");
257  BDM_ASSIGN_CONFIG_VALUE(visualization_interval, "visualization.interval");
259  "visualization.export_generate_pvsm");
261  "visualization.compress_pv_files");
262 
263  // visualize_agents
264  auto visualize_agentstarr = config->get_table_array("visualize_agent");
265  if (visualize_agentstarr) {
266  for (const auto& table : *visualize_agentstarr) {
267  // We do a 'redundant' check here, because `get_as` on Mac OS does not
268  // catch the exception when the "name" is not defined in the bdm.toml
269  // Same goes for all the other redundant checks
270  if (table->contains("name")) {
271  auto name = table->get_as<std::string>("name");
272  if (!name) {
273  Log::Warning("AssignFromConfig",
274  "Missing name for attribute visualize_agent");
275  continue;
276  }
277 
278  if (table->contains("additional_data_members")) {
279  auto dm_option =
280  table->get_array_of<std::string>("additional_data_members");
281 
282  std::set<std::string> data_members;
283  for (const auto& val : *dm_option) {
284  data_members.insert(val);
285  }
286  visualize_agents[*name] = data_members;
287  } else {
288  std::set<std::string> data_members;
289  visualize_agents[*name] = data_members;
290  }
291  }
292  }
293  }
294 
295  // visualize_diffusion
296  auto visualize_diffusiontarr = config->get_table_array("visualize_diffusion");
297  if (visualize_diffusiontarr) {
298  for (const auto& table : *visualize_diffusiontarr) {
299  if (table->contains("name")) {
300  auto name = table->get_as<std::string>("name");
301  if (!name) {
302  Log::Warning("AssignFromConfig",
303  "Missing name for attribute visualize_diffusion");
304  continue;
305  }
306 
308  vd.name = *name;
309 
310  if (table->contains("concentration")) {
311  auto concentration = table->get_as<bool>("concentration");
312  if (concentration) {
313  vd.concentration = *concentration;
314  }
315  }
316  if (table->contains("gradient")) {
317  auto gradient = table->get_as<bool>("gradient");
318  if (gradient) {
319  vd.gradient = *gradient;
320  }
321  }
322 
323  visualize_diffusion.push_back(vd);
324  }
325  }
326  }
327 
328  // unschedule_default_operations
329  if (config->get_table("simulation")) {
330  auto disabled_ops =
331  config->get_table("simulation")
332  ->get_array_of<std::string>("unschedule_default_operations");
333  for (const auto& op : *disabled_ops) {
334  unschedule_default_operations.push_back(op);
335  }
336  }
337 
338  // performance group
340  "performance.scheduling_batch_size");
342  "performance.detect_static_agents");
343  BDM_ASSIGN_CONFIG_VALUE(cache_neighbors, "performance.cache_neighbors");
344  BDM_ASSIGN_CONFIG_VALUE(use_bdm_mem_mgr, "performance.use_bdm_mem_mgr");
346  "performance.mem_mgr_aligned_pages_shift");
348  "performance.mem_mgr_growth_rate");
350  "performance.mem_mgr_max_mem_per_thread_factor");
352  "performance.minimize_memory_while_rebalancing");
353  AssignMappedDataArrayMode(config, this);
354 
355  // development group
356  BDM_ASSIGN_CONFIG_VALUE(statistics, "development.statistics");
357  BDM_ASSIGN_CONFIG_VALUE(debug_numa, "development.debug_numa");
359  "development.show_simulation_step");
360  BDM_ASSIGN_CONFIG_VALUE(use_progress_bar, "development.use_progress_bar");
361 
362  // experimental group
363  BDM_ASSIGN_CONFIG_VALUE(compute_target, "experimental.compute_target");
364  BDM_ASSIGN_CONFIG_VALUE(opencl_debug, "experimental.opencl_debug");
365  BDM_ASSIGN_CONFIG_VALUE(preferred_gpu, "experimental.preferred_gpu");
366 }
367 
368 } // namespace bdm
bdm::Param::VisualizeDiffusion
Definition: param.h:388
bdm::Param::visualization_engine
std::string visualization_engine
Definition: param.h:293
bdm::Param::use_progress_bar
bool use_progress_bar
Definition: param.h:607
BDM_ASSIGN_CONFIG_VALUE
#define BDM_ASSIGN_CONFIG_VALUE(variable, config_key)
Definition: cpptoml.h:18
bdm::Param::mapped_data_array_mode
Param::MappedDataArrayMode mapped_data_array_mode
Definition: param.h:555
bdm::Param::groups_
std::unordered_map< ParamGroupUid, ParamGroup * > groups_
Definition: param.h:654
bdm::Param::Param
Param()
Definition: param.cc:42
bdm::Param::detect_static_agents
bool detect_static_agents
Definition: param.h:470
bdm
Definition: agent.cc:39
bdm::Param::insitu_visualization
bool insitu_visualization
Definition: param.h:304
bdm::Param::debug_numa
bool debug_numa
Definition: param.h:586
optimization_param.h
bdm::Param::visualize_agents
std::map< std::string, std::set< std::string > > visualize_agents
JSON_object.
Definition: param.h:386
bdm::Param::ToJsonString
std::string ToJsonString() const
Definition: param.cc:108
bdm::Param::mem_mgr_aligned_pages_shift
uint64_t mem_mgr_aligned_pages_shift
Definition: param.h:499
cpptoml.h
bdm::Param::use_bdm_mem_mgr
bool use_bdm_mem_mgr
Definition: param.h:487
bdm::Param::unibn_bucketsize
uint32_t unibn_bucketsize
Definition: param.h:140
bdm::Param::cache_neighbors
bool cache_neighbors
Definition: param.h:480
bdm::Param::export_visualization
bool export_visualization
Definition: param.h:312
bdm::Param::show_simulation_step
uint64_t show_simulation_step
Definition: param.h:595
bdm::Param::diffusion_boundary_condition
std::string diffusion_boundary_condition
Definition: param.h:244
bdm::ParamGroup::GetUid
virtual ParamGroupUid GetUid() const =0
bdm::Param::backup_file
std::string backup_file
Definition: param.h:159
bdm::ParamGroupUid
uint64_t ParamGroupUid
Definition: param_group.h:26
bdm::Param::RegisterParamGroup
static void RegisterParamGroup(ParamGroup *param)
Definition: param.cc:37
bdm::Param::VisualizeDiffusion::gradient
bool gradient
Definition: param.h:391
bdm::Param::mem_mgr_max_mem_per_thread_factor
uint64_t mem_mgr_max_mem_per_thread_factor
Definition: param.h:522
bdm::Param::minimize_memory_while_rebalancing
bool minimize_memory_while_rebalancing
Definition: param.h:536
bdm::Param::compute_target
std::string compute_target
Definition: param.h:625
bdm::Param::mem_mgr_growth_rate
real_t mem_mgr_growth_rate
Definition: param.h:508
bdm::Param::backup_interval
uint32_t backup_interval
Definition: param.h:177
bdm::Param::opencl_debug
bool opencl_debug
Definition: param.h:633
bdm::Log::Warning
static void Warning(const std::string &location, const Args &... parts)
Prints warning message.
Definition: log.h:67
bdm::Param::diffusion_method
std::string diffusion_method
Definition: param.h:257
bdm::Param::max_bound
real_t max_bound
Definition: param.h:236
bdm::Param::unschedule_default_operations
std::vector< std::string > unschedule_default_operations
Definition: param.h:99
bdm::OptimizationParam
Definition: optimization_param.h:24
bdm::Param::pv_insitu_pipelinearguments
std::string pv_insitu_pipelinearguments
Definition: param.h:343
bdm::Param::registered_groups_
static std::unordered_map< ParamGroupUid, std::unique_ptr< ParamGroup > > registered_groups_
Definition: param.h:653
bdm::Param::simulation_time_step
real_t simulation_time_step
Definition: param.h:185
bdm::Param::scheduling_batch_size
uint64_t scheduling_batch_size
Definition: param.h:437
bdm::Param::VisualizeDiffusion::name
std::string name
Definition: param.h:389
bdm::Param::visualization_compress_pv_files
bool visualization_compress_pv_files
Definition: param.h:427
bdm::Param::min_bound
real_t min_bound
Definition: param.h:227
bdm::ParamGroup
Interface for parameter groups.
Definition: param_group.h:45
bdm::Concat
std::string Concat(const Args &... parts)
Concatenates all arguments into a string. Equivalent to streaming all arguments into a stringstream a...
Definition: string.h:70
bdm::Param::MergeJsonPatch
void MergeJsonPatch(const std::string &patch)
Definition: param.cc:126
bdm::Param::~Param
~Param()
Definition: param.cc:50
bdm::Log::Fatal
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
Definition: log.h:115
log.h
bdm::Param::simulation_max_displacement
real_t simulation_max_displacement
Definition: param.h:194
bdm::UnflattenGroups
json UnflattenGroups(const json &j_flattened, const json &j_original)
Definition: param.cc:89
bdm::Param::AssignFromConfig
void AssignFromConfig(const std::shared_ptr< cpptoml::table > &)
Assign values from config file to variables.
Definition: param.cc:220
bdm::Param::random_seed
uint64_t random_seed
Definition: param.h:90
bdm::Param::environment
std::string environment
Definition: param.h:122
bdm::Param::root_visualization
bool root_visualization
Definition: param.h:320
bdm::FlattenGroups
json FlattenGroups(const json &j_document)
Definition: param.cc:73
bdm::Param::visualization_interval
uint32_t visualization_interval
Definition: param.h:353
bdm::Param::output_dir
std::string output_dir
Definition: param.h:113
bdm::Param::calculate_gradients
bool calculate_gradients
Definition: param.h:265
bdm::Param::pv_insitu_pipeline
std::string pv_insitu_pipeline
Definition: param.h:328
bdm::ParamGroupUidGenerator::Get
static ParamGroupUidGenerator * Get()
Definition: param_group.cc:20
bdm::Param::thread_safety_mechanism
ThreadSafetyMechanism thread_safety_mechanism
Definition: param.h:281
bdm::Param::VisualizeDiffusion::concentration
bool concentration
Definition: param.h:390
bdm::Param::preferred_gpu
int preferred_gpu
Definition: param.h:641
param.h
bdm::Param::restore_file
std::string restore_file
Definition: param.h:169
bdm::Param::visualize_diffusion
std::vector< VisualizeDiffusion > visualize_diffusion
Definition: param.h:416
bdm::Param
Definition: param.h:35
bdm::ParamGroupUidGenerator::NewUid
ParamGroupUid NewUid()
Definition: param_group.cc:27
bdm::Param::visualization_export_generate_pvsm
bool visualization_export_generate_pvsm
Definition: param.h:362
bdm::AssignThreadSafetyMechanism
void AssignThreadSafetyMechanism(const std::shared_ptr< cpptoml::table > &config, Param *param)
Definition: param.cc:149
bdm::AssignBoundSpaceMode
void AssignBoundSpaceMode(const std::shared_ptr< cpptoml::table > &config, Param *param)
Definition: param.cc:196
bdm::Param::statistics
bool statistics
Definition: param.h:568
bdm::Param::Restore
void Restore(Param &&other)
Definition: param.cc:57
bdm::AssignMappedDataArrayMode
void AssignMappedDataArrayMode(const std::shared_ptr< cpptoml::table > &config, Param *param)
Definition: param.cc:170
bdm::Param::nanoflann_depth
uint32_t nanoflann_depth
Definition: param.h:131