world.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2019-2021 by
  4. * The Salk Institute for Biological Studies and
  5. * Pittsburgh Supercomputing Center, Carnegie Mellon University
  6. *
  7. * Use of this source code is governed by an MIT-style
  8. * license that can be found in the LICENSE file or at
  9. * https://opensource.org/licenses/MIT.
  10. *
  11. ******************************************************************************/
  12. #ifndef SRC4_WORLD_H_
  13. #define SRC4_WORLD_H_
  14. #include <time.h>
  15. #ifndef _WIN64
  16. #include <sys/time.h> // Linux include
  17. #include <sys/resource.h> // Linux include
  18. #endif
  19. #include <functional>
  20. #include <chrono>
  21. #include <vector>
  22. #include <string>
  23. #include <set>
  24. #include <map>
  25. #include <iostream>
  26. #include "bng/bng.h"
  27. #include "api/checkpoint_signals.h"
  28. #include "partition.h"
  29. #include "scheduler.h"
  30. #include "geometry.h"
  31. #include "count_buffer.h"
  32. #include "memory_limit_checker.h"
  33. #include "logging.h"
  34. #include "rng.h"
  35. namespace Json {
  36. class Value;
  37. }
  38. namespace MCell {
  39. namespace API {
  40. class Model;
  41. class Callbacks;
  42. enum class BNGSimulationMethod;
  43. }
  44. class MolOrRxnCountEvent;
  45. class World {
  46. public:
  47. World(API::Callbacks& callbacks_);
  48. ~World();
  49. // MCell MDL mode
  50. void init_and_run_simulation(const bool dump_initial_state = false, const bool dump_with_geometry = false);
  51. void init_simulation(const double start_time);
  52. // MCell Python mode, init_simulation must be called first
  53. // returns number of executed iterations
  54. uint64_t run_n_iterations(
  55. const uint64_t num_iterations,
  56. const bool terminate_last_iteration_after_viz_output = false // used when ending simulation
  57. );
  58. void end_simulation(const bool print_final_report = true);
  59. // used by converters
  60. void create_initial_surface_region_release_event();
  61. // checkpointing - called from signal handler
  62. void set_to_create_checkpoint_event_from_signal_hadler(const int signo, API::Model* model) {
  63. signaled_checkpoint_signo = signo;
  64. signaled_checkpoint_model = model;
  65. }
  66. void schedule_checkpoint_event(
  67. const uint64_t iteration, const bool continue_simulation, const API::CheckpointSaveEventContext& ctx);
  68. // -------------- diverse getters -----------------------------
  69. const SimulationConfig& get_config() {
  70. return config;
  71. }
  72. uint64_t get_current_iteration() const {
  73. return stats.get_current_iteration();
  74. }
  75. API::Callbacks& get_callbacks() {
  76. return callbacks;
  77. }
  78. // -------------- partition manipulation methods --------------
  79. partition_id_t get_partition_index(const Vec3& pos) {
  80. // for now a slow approach, later some hashing/memoization might be needed
  81. for (partition_id_t i = 0; i < partitions.size(); i++) {
  82. if (partitions[i].in_this_partition(pos)) {
  83. return i;
  84. }
  85. }
  86. return PARTITION_ID_INVALID;
  87. }
  88. // add a partition in a predefined 'lattice' that contains point pos as its llf point
  89. // size is given by config
  90. partition_id_t add_partition(const Vec3& partition_llf) {
  91. assert(config.partition_edge_length != 0);
  92. assert(get_partition_index(partition_llf) == PARTITION_ID_INVALID && "Partition must not exist");
  93. partitions.push_back(Partition(partitions.size(), partition_llf, config, bng_engine, stats));
  94. return partitions.size() - 1;
  95. }
  96. Partition& get_partition(partition_id_t i) {
  97. assert(i < partitions.size());
  98. return partitions[i];
  99. }
  100. const Partition& get_partition(partition_id_t i) const {
  101. assert(i < partitions.size());
  102. return partitions[i];
  103. }
  104. PartitionVector& get_partitions() {
  105. return partitions;
  106. }
  107. // -------------- object id counters --------------
  108. wall_id_t get_next_wall_id() {
  109. wall_id_t res = next_wall_id;
  110. next_wall_id++;
  111. return res;
  112. }
  113. region_id_t get_next_region_id() {
  114. region_id_t res = next_region_id;
  115. next_region_id++;
  116. return res;
  117. }
  118. geometry_object_id_t get_next_geometry_object_id() {
  119. geometry_object_id_t res = next_geometry_object_id;
  120. next_geometry_object_id++;
  121. return res;
  122. }
  123. void print_periodic_stats() const;
  124. void dump(const bool with_geometry = false);
  125. // exports model geometry to Wavefront OBJ format
  126. void export_geometry_to_obj(const std::string& files_prefix) const;
  127. // the export to directory is usually called periodically and the output is used for visualization
  128. void export_data_model_to_dir(const std::string& prefix, const bool only_for_viz = true) const;
  129. void export_data_model(const std::string& file_name, const bool only_for_viz) const;
  130. void to_data_model(Json::Value& root, const bool only_for_viz) const;
  131. // ---------------------- other ----------------------
  132. BNG::SpeciesContainer& get_all_species() { return bng_engine.get_all_species(); }
  133. const BNG::SpeciesContainer& get_all_species() const { return bng_engine.get_all_species(); }
  134. BNG::RxnContainer& get_all_rxns() { return bng_engine.get_all_rxns(); }
  135. const BNG::RxnContainer& get_all_rxns() const { return bng_engine.get_all_rxns(); }
  136. count_buffer_id_t create_dat_count_buffer(
  137. const std::string file_name, const size_t buffer_size, const bool open_for_append = false);
  138. count_buffer_id_t create_gdat_count_buffer(
  139. const std::string file_name, const std::vector<std::string>& column_names,
  140. const size_t buffer_size, const bool open_for_append);
  141. CountBuffer& get_count_buffer(const count_buffer_id_t id) {
  142. assert(id < count_buffers.size());
  143. return count_buffers[id];
  144. }
  145. const CountBuffer& get_count_buffer(const count_buffer_id_t id) const {
  146. assert(id < count_buffers.size());
  147. return count_buffers[id];
  148. }
  149. GeometryObject& get_geometry_object(const geometry_object_id_t id) {
  150. // TODO: there will be multiple places where geom object id and index are mixed
  151. return get_partition(0).get_geometry_object_by_id(id);
  152. }
  153. const GeometryObject& get_geometry_object(const geometry_object_id_t id) const {
  154. // TODO: there will be multiple places where geom object id and index are mixed
  155. return get_partition(0).get_geometry_object_by_id(id);
  156. }
  157. const Region& get_region(const region_id_t id) const {
  158. return get_partition(0).get_region_by_id(id);
  159. }
  160. const Region* find_region_by_name(const std::string& name) const {
  161. return get_partition(0).find_region_by_name(name);
  162. }
  163. static uint64_t determine_output_frequency(uint64_t iterations);
  164. bool check_for_overlapped_walls();
  165. void reset_unimol_rxn_times(const BNG::rxn_rule_id_t rxn_rule_id);
  166. // gives ownership of the event to this World object
  167. void add_unscheduled_count_event(MolOrRxnCountEvent* e) {
  168. unscheduled_count_events.push_back(e);
  169. }
  170. void flush_buffers();
  171. void flush_and_close_buffers();
  172. // prints message, flushes buffers, and terminates
  173. void fatal_error(const std::string& msg);
  174. private:
  175. void check_checkpointing_signal();
  176. uint64_t time_to_iteration(const double time);
  177. void init_fpu();
  178. void init_counted_volumes();
  179. void initialization_to_data_model(Json::Value& mcell_node) const;
  180. void export_data_layout() const;
  181. public:
  182. // single instance for the whole mcell simulator,
  183. // used as constants during simulation
  184. SimulationConfig config;
  185. BNG::BNGEngine bng_engine;
  186. SimulationStats stats;
  187. // owned by API::Model or references a global instance in case of MDL mode
  188. API::Callbacks& callbacks;
  189. mutable Scheduler scheduler; // scheduler might need to do some internal reorganization
  190. std::vector<MolOrRxnCountEvent*> unscheduled_count_events;
  191. uint64_t total_iterations; // number of iterations to simulate - move to Sim config
  192. rng_state rng; // single state for the random number generator
  193. private:
  194. PartitionVector partitions;
  195. CountBufferVector count_buffers;
  196. // periodic check of used memory using timer
  197. MemoryLimitChecker memory_limit_checker;
  198. // global ID counters
  199. wall_id_t next_wall_id;
  200. region_id_t next_region_id;
  201. geometry_object_id_t next_geometry_object_id;
  202. // used by run_n_iterations to know whether the simulation was
  203. // already initialized
  204. bool simulation_initialized;
  205. // set in run_n_iterations to know whether we should report
  206. // final viz and rxn output in end_simulation
  207. bool run_n_iterations_terminated_with_checkpoint;
  208. // used to know whether we already reported final simulation stats
  209. bool simulation_ended;
  210. // buffers can be flushed only once
  211. bool buffers_flushed;
  212. // several variables to report simulation time
  213. std::chrono::time_point<std::chrono::steady_clock> previous_progress_report_time;
  214. rusage sim_start_time;
  215. bool it1_start_time_set;
  216. rusage it1_start_time; // time when 1st iteration started
  217. std::chrono::time_point<std::chrono::steady_clock> previous_buffer_flush_time;
  218. // and to nicely report simulation progress
  219. uint64_t previous_iteration;
  220. // SIGNO_NOT_SIGNALED (-1) if not signaled, supported values are SIGUSR1, SIGUSR2, and SIGALRM
  221. int signaled_checkpoint_signo;
  222. // checkpointing requires model pointer, do not use this for anything else,
  223. // is not nullptr only when a checkpoint is scheduled
  224. API::Model* signaled_checkpoint_model;
  225. };
  226. } // namespace mcell
  227. #endif // SRC4_WORLD_H_