123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- /******************************************************************************
- *
- * Copyright (C) 2019-2021 by
- * The Salk Institute for Biological Studies and
- * Pittsburgh Supercomputing Center, Carnegie Mellon University
- *
- * Use of this source code is governed by an MIT-style
- * license that can be found in the LICENSE file or at
- * https://opensource.org/licenses/MIT.
- *
- ******************************************************************************/
- #ifndef SRC4_WORLD_H_
- #define SRC4_WORLD_H_
- #include <time.h>
- #ifndef _WIN64
- #include <sys/time.h> // Linux include
- #include <sys/resource.h> // Linux include
- #endif
- #include <functional>
- #include <chrono>
- #include <vector>
- #include <string>
- #include <set>
- #include <map>
- #include <iostream>
- #include "bng/bng.h"
- #include "api/checkpoint_signals.h"
- #include "partition.h"
- #include "scheduler.h"
- #include "geometry.h"
- #include "count_buffer.h"
- #include "memory_limit_checker.h"
- #include "logging.h"
- #include "rng.h"
- namespace Json {
- class Value;
- }
- namespace MCell {
- namespace API {
- class Model;
- class Callbacks;
- enum class BNGSimulationMethod;
- }
- class MolOrRxnCountEvent;
- class World {
- public:
- World(API::Callbacks& callbacks_);
- ~World();
- // MCell MDL mode
- void init_and_run_simulation(const bool dump_initial_state = false, const bool dump_with_geometry = false);
- void init_simulation(const double start_time);
- // MCell Python mode, init_simulation must be called first
- // returns number of executed iterations
- uint64_t run_n_iterations(
- const uint64_t num_iterations,
- const bool terminate_last_iteration_after_viz_output = false // used when ending simulation
- );
- void end_simulation(const bool print_final_report = true);
- // used by converters
- void create_initial_surface_region_release_event();
- // checkpointing - called from signal handler
- void set_to_create_checkpoint_event_from_signal_hadler(const int signo, API::Model* model) {
- signaled_checkpoint_signo = signo;
- signaled_checkpoint_model = model;
- }
- void schedule_checkpoint_event(
- const uint64_t iteration, const bool continue_simulation, const API::CheckpointSaveEventContext& ctx);
- // -------------- diverse getters -----------------------------
- const SimulationConfig& get_config() {
- return config;
- }
- uint64_t get_current_iteration() const {
- return stats.get_current_iteration();
- }
- API::Callbacks& get_callbacks() {
- return callbacks;
- }
- // -------------- partition manipulation methods --------------
- partition_id_t get_partition_index(const Vec3& pos) {
- // for now a slow approach, later some hashing/memoization might be needed
- for (partition_id_t i = 0; i < partitions.size(); i++) {
- if (partitions[i].in_this_partition(pos)) {
- return i;
- }
- }
- return PARTITION_ID_INVALID;
- }
- // add a partition in a predefined 'lattice' that contains point pos as its llf point
- // size is given by config
- partition_id_t add_partition(const Vec3& partition_llf) {
- assert(config.partition_edge_length != 0);
- assert(get_partition_index(partition_llf) == PARTITION_ID_INVALID && "Partition must not exist");
- partitions.push_back(Partition(partitions.size(), partition_llf, config, bng_engine, stats));
- return partitions.size() - 1;
- }
- Partition& get_partition(partition_id_t i) {
- assert(i < partitions.size());
- return partitions[i];
- }
- const Partition& get_partition(partition_id_t i) const {
- assert(i < partitions.size());
- return partitions[i];
- }
- PartitionVector& get_partitions() {
- return partitions;
- }
- // -------------- object id counters --------------
- wall_id_t get_next_wall_id() {
- wall_id_t res = next_wall_id;
- next_wall_id++;
- return res;
- }
- region_id_t get_next_region_id() {
- region_id_t res = next_region_id;
- next_region_id++;
- return res;
- }
- geometry_object_id_t get_next_geometry_object_id() {
- geometry_object_id_t res = next_geometry_object_id;
- next_geometry_object_id++;
- return res;
- }
- void print_periodic_stats() const;
- void dump(const bool with_geometry = false);
- // exports model geometry to Wavefront OBJ format
- void export_geometry_to_obj(const std::string& files_prefix) const;
- // the export to directory is usually called periodically and the output is used for visualization
- void export_data_model_to_dir(const std::string& prefix, const bool only_for_viz = true) const;
- void export_data_model(const std::string& file_name, const bool only_for_viz) const;
- void to_data_model(Json::Value& root, const bool only_for_viz) const;
- // ---------------------- other ----------------------
- BNG::SpeciesContainer& get_all_species() { return bng_engine.get_all_species(); }
- const BNG::SpeciesContainer& get_all_species() const { return bng_engine.get_all_species(); }
- BNG::RxnContainer& get_all_rxns() { return bng_engine.get_all_rxns(); }
- const BNG::RxnContainer& get_all_rxns() const { return bng_engine.get_all_rxns(); }
- count_buffer_id_t create_dat_count_buffer(
- const std::string file_name, const size_t buffer_size, const bool open_for_append = false);
- count_buffer_id_t create_gdat_count_buffer(
- const std::string file_name, const std::vector<std::string>& column_names,
- const size_t buffer_size, const bool open_for_append);
- CountBuffer& get_count_buffer(const count_buffer_id_t id) {
- assert(id < count_buffers.size());
- return count_buffers[id];
- }
- const CountBuffer& get_count_buffer(const count_buffer_id_t id) const {
- assert(id < count_buffers.size());
- return count_buffers[id];
- }
- GeometryObject& get_geometry_object(const geometry_object_id_t id) {
- // TODO: there will be multiple places where geom object id and index are mixed
- return get_partition(0).get_geometry_object_by_id(id);
- }
- const GeometryObject& get_geometry_object(const geometry_object_id_t id) const {
- // TODO: there will be multiple places where geom object id and index are mixed
- return get_partition(0).get_geometry_object_by_id(id);
- }
- const Region& get_region(const region_id_t id) const {
- return get_partition(0).get_region_by_id(id);
- }
- const Region* find_region_by_name(const std::string& name) const {
- return get_partition(0).find_region_by_name(name);
- }
- static uint64_t determine_output_frequency(uint64_t iterations);
- bool check_for_overlapped_walls();
- void reset_unimol_rxn_times(const BNG::rxn_rule_id_t rxn_rule_id);
- // gives ownership of the event to this World object
- void add_unscheduled_count_event(MolOrRxnCountEvent* e) {
- unscheduled_count_events.push_back(e);
- }
- void flush_buffers();
- void flush_and_close_buffers();
- // prints message, flushes buffers, and terminates
- void fatal_error(const std::string& msg);
- private:
- void check_checkpointing_signal();
- uint64_t time_to_iteration(const double time);
- void init_fpu();
- void init_counted_volumes();
- void initialization_to_data_model(Json::Value& mcell_node) const;
- void export_data_layout() const;
- public:
- // single instance for the whole mcell simulator,
- // used as constants during simulation
- SimulationConfig config;
- BNG::BNGEngine bng_engine;
- SimulationStats stats;
- // owned by API::Model or references a global instance in case of MDL mode
- API::Callbacks& callbacks;
- mutable Scheduler scheduler; // scheduler might need to do some internal reorganization
- std::vector<MolOrRxnCountEvent*> unscheduled_count_events;
- uint64_t total_iterations; // number of iterations to simulate - move to Sim config
- rng_state rng; // single state for the random number generator
- private:
- PartitionVector partitions;
- CountBufferVector count_buffers;
- // periodic check of used memory using timer
- MemoryLimitChecker memory_limit_checker;
- // global ID counters
- wall_id_t next_wall_id;
- region_id_t next_region_id;
- geometry_object_id_t next_geometry_object_id;
- // used by run_n_iterations to know whether the simulation was
- // already initialized
- bool simulation_initialized;
- // set in run_n_iterations to know whether we should report
- // final viz and rxn output in end_simulation
- bool run_n_iterations_terminated_with_checkpoint;
- // used to know whether we already reported final simulation stats
- bool simulation_ended;
- // buffers can be flushed only once
- bool buffers_flushed;
- // several variables to report simulation time
- std::chrono::time_point<std::chrono::steady_clock> previous_progress_report_time;
- rusage sim_start_time;
- bool it1_start_time_set;
- rusage it1_start_time; // time when 1st iteration started
- std::chrono::time_point<std::chrono::steady_clock> previous_buffer_flush_time;
- // and to nicely report simulation progress
- uint64_t previous_iteration;
- // SIGNO_NOT_SIGNALED (-1) if not signaled, supported values are SIGUSR1, SIGUSR2, and SIGALRM
- int signaled_checkpoint_signo;
- // checkpointing requires model pointer, do not use this for anything else,
- // is not nullptr only when a checkpoint is scheduled
- API::Model* signaled_checkpoint_model;
- };
- } // namespace mcell
- #endif // SRC4_WORLD_H_
|