openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
ION_IF.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
2 // SPDX-License-Identifier: LicenseRef-APL-1.1
3 
21 #ifndef IONIC_IF_H
22 #define IONIC_IF_H
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stddef.h>
28 #include <stdexcept>
29 #include "LUT.h"
30 #include "ODEint.h"
31 #include <math.h>
32 #include <assert.h>
33 #include <memory>
34 #include <functional>
35 #include <vector>
36 #include <utility>
37 #ifdef _OPENMP
38 #include <omp.h>
39 #endif
40 #ifdef HAS_CUDA_MODEL
41 #include <cuda_runtime.h>
42 #endif
43 #ifdef HAS_ROCM_MODEL
44 #include <hip/hip_runtime.h>
45 #endif
46 
47 #include "basics.h"
48 #include "target.h"
49 
50 #ifdef I
51 #undef I
52 #endif
53 
54 namespace limpet {
55 
56 #ifndef M_PI //C99 does not define M_PI
57 #define M_PI 3.14159265358979323846264338327
58 #endif
59 
60 //Defines used in Slava's LIMPET model '
61 #define heav(x) ( (x)<0 ? 0 : 1)
62 #define sign(x) ( (x)<0 ? -1 : 1 )
63 #define square(x) ((x)*(x))
64 #define cube(x) ((x)*(x)*(x))
65 
66 // MPI message tags used in the IMP world
67 #define MPI_RESTORE_IMP_POLL_BUFSIZE_TAG 10
68 #define MPI_RESTORE_IMP_SNDRCV_BUFFER_TAG 11
69 #define MPI_DUMP_IMP_POLL_BUFSIZE_TAG 20
70 #define MPI_DUMP_IMP_SNDRCV_BUFFER_TAG 21
71 #define MPI_DUMP_SVS_POLL_BUFSIZE_TAG 30
72 #define MPI_DUMP_SVS_SNDRCV_BUFFER_TAG 31
73 
80 struct tc_grp {
81  float dt;
82  int skp;
83  int rat;
84  int update;
85 };
86 
91 struct ts {
92  int cnt;
93  int ng;
95 };
96 
97 
100 struct SV_TAB {
101  int svSize;
102  int numSeg;
103  void *y;
106 };
107 
118 #define NDEF 0
119 struct cell_geom {
120  float SVratio=NDEF;
121  float v_cell=NDEF;
122  float a_cap=NDEF;
123  float fr_myo=NDEF;
124  float sl_i2c=NDEF;
125 };
126 
127 }
128 #include "ion_type.h"
129 namespace limpet {
130 
131 struct IMPinfo {
132  char *name;
133  int sz;
134  int nplug;
136  bool compatible;
137  int map;
138  int offset;
139  uint64_t fingerprint;
140 };
141 
149 class LutSet {
150 public:
151  explicit LutSet(Target target) : target(target) {}
152  ~LutSet();
153 
154  LutSet(const LutSet&) = delete;
155  LutSet& operator=(const LutSet&) = delete;
156 
157  std::vector<LUT> host;
158  LUT* device = nullptr;
159  size_t device_count = 0;
160 
161 private:
162  Target target;
163 };
164 
168 class IonIfBase {
169 private:
170  // Information about the model type.
171  const IonType& _type;
172  node_count_t _num_node;
173  IonIfBase* _parent;
174  std::vector<IonIfBase*> _plugins;
175  uint32_t _reqdat;
177  uint32_t _moddat;
179 public:
180  int miifIdx;
182 protected:
184 private:
185  cell_geom _cgeom;
186  float dt;
187  std::shared_ptr<LutSet> _tables;
188  LUT* _tables_d = nullptr;
189  size_t _n_tables_d = 0;
190  GlobalData_t **ldata = nullptr;
196  struct sv_field { std::string name; int off; int sz; int type; };
197  mutable std::vector<sv_field> _sv_layout;
198  mutable bool _sv_layout_valid = false;
199 
201  const std::vector<sv_field>& sv_layout() const;
202 
203 protected:
204  bool has_lookup_tables() const { return this->_tables != nullptr; }
205 
206 public:
215  IonIfBase(const IonType& type, Target target, node_count_t num_node, const std::vector<std::reference_wrapper<IonType>>& plugins);
216 
220  virtual ~IonIfBase();
221 
228  const IonType& get_type() const;
229 
235  node_count_t get_num_node() const;
236 
242  std::size_t get_num_threads() const;
243 
249  IonIfBase* parent() const;
250 
251  // VERY UNRECOMMENDED TO CALL, THIS IS ONLY USED FOR AN UGLY HACK.
252  void set_parent(IonIfBase* parent);
253 
259  std::vector<IonIfBase*>& plugins();
260 
266  uint32_t get_reqdat() const;
267 
273  uint32_t get_moddat() const;
274 
280  void set_moddat(uint32_t data);
281 
287 #if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL
288  __device__ __host__
289 #endif
291  return this->_cgeom;
292  }
293 
299  float get_dt() const;
300 
306  void set_dt(float dt);
307 
308 
314  ts& get_tstp();
315 
325  virtual void *get_sv_address() = 0;
326 
333  virtual std::size_t get_sv_size() const = 0;
334 
341 //#if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL
342 // __device__ __host__
343 //#endif
344 // SV_TAB& sv_tab() {
345 // return this->_sv_tab;
346 // }
347 
354  std::vector<LUT>& tables();
355 
363 #if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL
364  __device__ __host__
365 #endif
366  LUT *tables_d() const {
367  return this->_tables_d;
368  }
369 
376  size_t get_n_tables_d() const;
377 
378 #if defined HAS_GPU_MODEL
379  __device__ __host__
380 #endif
381  Target get_target() const {
382  return this->_target;
383  };
384 
385  virtual void set_target(Target target);
386 
391  void initialize_params();
392 
404  virtual void initialize(double dt, GlobalData_t **impdat);
405 
411  virtual void initialize_state(double dt, GlobalData_t **impdat);
412 
420  void compute(node_index_t start, node_index_t end, GlobalData_t** data);
421 
433  char* fill_buf(char *buf, int* n, opencarp::Salt_list *l) const;
434 
451  size_t *offset, IMPinfo *impinfo, const global_node_index_t* loc2canon);
452 
474  IIF_Mask_t *mask, size_t *offset, IMPinfo *impinfo,
475  const global_node_index_t* loc2canon);
476 
488  void get_sv_layout(std::vector<std::pair<int, int>>& fields) const;
489 
504  template <class Fn>
505  void for_each_sv_field(node_index_t node, const std::vector<std::pair<int, int>>& fields, Fn&& fn) {
506  const std::size_t vec_size = this->get_type().dlo_vector_size();
507  char* block_base = static_cast<char*>(this->get_sv_address())
508  + (static_cast<std::size_t>(node) / vec_size) * this->get_sv_size();
509  const std::size_t lane = static_cast<std::size_t>(node) % vec_size;
510  for (const auto& f : fields)
511  fn(block_base + f.first + lane * static_cast<std::size_t>(f.second),
512  static_cast<std::size_t>(f.second));
513  }
514 
522  size_t get_sv_per_node_size() const;
523 
534  uint64_t sv_fingerprint() const;
535 
543  int dump_luts(bool zipped);
544 
550  void destroy_luts();
551 
557  void rebuild_lookup_tables();
558 
564  void share_lookup_tables_from(const IonIfBase& other);
565 
592  void tune(const char *im_par, const char *plugs, const char *plug_par);
593 
601  int read_svs(FILE* file);
602 
603  int write_svs(FILE* file, node_index_t node);
604 
614  virtual void copy_SVs_from(IonIfBase& other, bool alloc) = 0;
615 
624  virtual void copy_configuration_from(IonIfBase& other) = 0;
625 
634  void copy_plugins_from(IonIfBase& other);
635 
642  void for_each(const std::function<void(IonIfBase&)>& consumer);
643 };
644 
655 template<typename T>
656 class IonIf : public IonIfBase {
664  struct has_rosenbrock_type {};
665  struct has_rosenbrock_vector_type {};
666  struct no_rosenbrock_type {};
667  public:
679  template<typename S>
680  class LimpetArray {
681  static constexpr bool is_void = std::is_void<S>::value;
684  S *_data;
685  std::size_t _size; //<! size of the SV array
686  bool _allocated = false;
687  Target _target;
688  public:
689 
693  LimpetArray() : _size(0), _target(Target::UNKNOWN) {
694  }
695 
702  LimpetArray(Target target, std::size_t size) : _size(size),
703  _target(target) {
704  this->allocate(target, size);
705  }
706 
711  // Check if memory was allocated, if it's the case, deallocate on the
712  // corresponding target
713  if (!is_void && _allocated) {
714  deallocate_on_target<S>(this->_target, this->_data);
715  }
716  }
717 
724  void allocate(Target target, std::size_t size) {
725  this->_size = size;
726  this->_target = target;
727  if (!is_void){
728  bool do_zero = false;
729  this->_data = allocate_on_target<S>(this->_target, this->_size, do_zero);
730  this->_allocated = true;
731  }
732  }
733 
740  template<typename Type = S>
741  typename std::enable_if<!std::is_void<Type>::value, std::size_t>::type get_element_size() const {
742  return sizeof(Type);
743  }
744 
745  template<typename Type = S>
746  typename std::enable_if<std::is_void<Type>::value, std::size_t>::type get_element_size() const {
747  return 0;
748  }
749 
755 #ifdef HAS_GPU_MODEL
756  __device__ __host__
757 #endif
758  S *data() const {
759  static_assert(!is_void, "The LimpetArray class can't be used with type 'void'");
760  return this->_data;
761  }
762 
768 #ifdef HAS_GPU_MODEL
769  __device__ __host__
770 #endif
771  std::size_t size() const {
772  static_assert(!is_void, "The LimpetArray class can't be used with type 'void'");
773  return this->_size;
774  }
775 
782  bool is_allocated() const {
783  return this->_allocated;
784  }
785 
793  if (this == &other) {
794  return *this;
795  }
796  this->_target = other._target;
797  this->_data = other._data;
798  this->_size = other._size;
799  if (other._allocated) {
800  this->_allocated = true;
801  other._allocated = false;
802  }
803  return *this;
804  }
805  };
806  private:
807  using SvTab = LimpetArray<typename T::state_type>;
808  using PrivateTab = LimpetArray<typename T::private_type>;
809  using PrivateVectorTab = LimpetArray<typename T::private_type_vector>;
810 
817  using rosenbrock_usage = typename std::conditional<std::is_void<typename T::private_type>::value, no_rosenbrock_type, typename std::conditional<std::is_void<typename T::private_type_vector>::value, has_rosenbrock_type, has_rosenbrock_vector_type>::type>::type;
818 
819  // These fields are C-style arrays because they need to be accessible from device code
820  SvTab _sv_tabs[Target::N_TARGETS];
821  typename T::params_type* _params[Target::N_TARGETS] = {nullptr};
822  PrivateTab _ion_private[Target::N_TARGETS];
823  PrivateVectorTab _ion_private_vector;
824  size_t private_sz;
825  public:
826 
834  IonIf(const IonType &type, Target target, node_count_t num_node, const
835  std::vector<std::reference_wrapper<IonType>>& plugins) : IonIfBase(type,
836  target, num_node, plugins) {
837  this->allocate_model_data();
838  }
839 
845  ~IonIf() {
846  for (int i = 0; i < Target::N_TARGETS; ++i) {
847  if (this->_params[i] != nullptr) {
848  deallocate_on_target((Target) i, this->_params[i]);
849  }
850  }
851  }
852 
858 #ifdef HAS_GPU_MODEL
859  __device__ __host__
860 #endif
861  typename T::params_type *params() const {
862  return this->_params[this->get_target()];
863  }
864 
870 #ifdef HAS_GPU_MODEL
871  __device__ __host__
872 #endif
874  return this->_sv_tabs[this->get_target()];
875  }
876 
883 #ifdef HAS_GPU_MODEL
884  __device__ __host__
885 #endif
887  return this->_ion_private[this->get_target()];
888  }
889 
891  if (this->get_target() != Target::MLIR_CPU) {
892  throw std::logic_error("the vectorized ion private structure can only be used with the MLIR_CPU (vectorized CPU) target");
893  }
894  return this->_ion_private_vector;
895  }
896 
902  void * get_sv_address() override {
903  return (void *) this->_sv_tabs[this->get_target()].data();
904  }
905 
911  std::size_t get_sv_size() const override {
912  return sizeof(typename T::state_type);
913  }
914 
923  void set_target(Target target) override {
924  Target old_target = this->get_target();
925  bool had_lookup_tables = this->has_lookup_tables();
926  IonIfBase::set_target(target);
927  this->allocate_model_data();
928  memcpy(this->sv_tab().data(), this->_sv_tabs[old_target].data(), this->sv_tab().size());
929  // TODO: Copy ion private data for Rosenbrock, making transformations as necessary between
930  // vectorized and non-vectorized structures
931  // memcpy(this->ion_private().data(), this->_ion_private[old_target].data(), this->ion_private().size());
932  memcpy(this->params(), this->_params[old_target], sizeof(typename T::params_type));
933  if (had_lookup_tables && old_target != this->get_target())
934  this->rebuild_lookup_tables();
935  }
936 
941  std::size_t vec_size = this->get_type().dlo_vector_size();
942  if (!this->_sv_tabs[this->get_target()].is_allocated())
943  this->_sv_tabs[this->get_target()] =
944  SvTab(this->get_target(), (this->get_num_node() + vec_size - 1) / vec_size);
945  if (!this->_ion_private[this->get_target()].is_allocated())
946  this->_ion_private[this->get_target()] = PrivateTab(this->get_target(), this->get_num_threads());
947  // The private vector structure is always made for the vectorized CPU target
948  if (!this->_ion_private_vector.is_allocated() && this->get_target() == Target::MLIR_CPU)
949  this->_ion_private_vector = PrivateVectorTab(this->get_target(), this->get_num_threads());
950  if (this->_params[this->get_target()] == nullptr)
951  this->_params[this->get_target()] = allocate_on_target<typename T::params_type>(this->get_target(), 1, true);
952  }
953 
963  void initialize(double dt, GlobalData_t **impdat) override {
964  IonIfBase::initialize(dt, impdat);
965  this->init_ion_private(rosenbrock_usage {});
966  }
967 
968  void initialize_state(double dt, GlobalData_t **impdat) override {
969  IonIfBase::initialize_state(dt, impdat);
970  this->init_ion_private(rosenbrock_usage {});
971  }
972 
978  void copy_configuration_from(IonIfBase& other_base) override {
979  if (this->get_type() != other_base.get_type()) {
980  throw std::logic_error("cannot copy IMP configuration between different model types");
981  }
982 
983  IonIf<T>& other = static_cast<IonIf<T>&>(other_base);
984  memcpy(this->params(), other.params(), sizeof(typename T::params_type));
985  this->cgeom() = other.cgeom();
986  }
987 
1002  void copy_SVs_from(IonIfBase& other_base, bool alloc) override {
1003  IonIf<T>& other = static_cast<IonIf<T>&>(other_base);
1004  int tcg_size = other.get_tstp().ng * sizeof(tc_grp);
1005 
1006  if (this->get_num_node() != other.get_num_node()) {
1007  throw std::logic_error("cannot copy SVs if both IMPs don't handle the same amount of cells");
1008  }
1009 
1010  memcpy(this->sv_tab().data(), other.sv_tab().data(), sizeof(typename T::state_type) * other.sv_tab().size());
1011  // Only copy memory when the model actually defines a private type
1012  this->copy_ion_private(other, rosenbrock_usage {});
1013  memcpy(this->get_tstp().tcg, other.get_tstp().tcg, tcg_size);
1014  }
1015 
1024  void copy_ion_private(IonIf<T>& other, has_rosenbrock_vector_type) {
1025  if (this->get_target() == Target::MLIR_CPU) {
1026  memcpy(this->ion_private_vector().data(), other.ion_private_vector().data(), sizeof(typename T::private_type_vector) * other.ion_private_vector().size());
1027  // Preserve the copied workspace, but keep its self-reference clone-local.
1028  for (std::size_t i = 0; i < this->ion_private_vector().size(); ++i)
1029  this->ion_private_vector().data()[i].IF = this;
1030  }
1031  else {
1032  memcpy(this->ion_private().data(), other.ion_private().data(), sizeof(typename T::private_type) * other.ion_private().size());
1033  // Preserve the copied workspace, but keep its self-reference clone-local.
1034  for (std::size_t i = 0; i < this->ion_private().size(); ++i)
1035  this->ion_private().data()[i].IF = this;
1036  }
1037  }
1038 
1047  void copy_ion_private(IonIf<T>& other, has_rosenbrock_type) {
1048  memcpy(this->ion_private().data(), other.ion_private().data(), sizeof(typename T::private_type) * other.ion_private().size());
1049  // Preserve the copied workspace, but keep its self-reference clone-local.
1050  for (std::size_t i = 0; i < this->ion_private().size(); ++i)
1051  this->ion_private().data()[i].IF = this;
1052  }
1053 
1059  void copy_ion_private(IonIf<T>& other, no_rosenbrock_type) { }
1060 
1066  void init_ion_private(has_rosenbrock_vector_type) {
1067  // We need to fill the vector version of the private data for vectorized CPU
1068  if (this->get_target() == Target::MLIR_CPU) {
1069  for (std::size_t i = 0; i < this->ion_private_vector().size(); ++i) {
1070  this->ion_private_vector().data()[i].node_number = 0;
1071  this->ion_private_vector().data()[i].IF = this;
1072  }
1073  }
1074  else {
1075  for (std::size_t i = 0; i < this->ion_private().size(); ++i) {
1076  this->ion_private().data()[i].node_number = 0;
1077  this->ion_private().data()[i].IF = this;
1078  }
1079  }
1080  }
1081 
1087  void init_ion_private(has_rosenbrock_type) {
1088  for (std::size_t i = 0; i < this->ion_private().size(); ++i) {
1089  this->ion_private().data()[i].node_number = 0;
1090  this->ion_private().data()[i].IF = this;
1091  }
1092  }
1093 
1100  void init_ion_private(no_rosenbrock_type) { }
1101 };
1102 
1103 /*
1104  function prototypes
1105  */
1106 
1107 void initialize_ts(ts *tstp, int ng, int *skp, double dt);
1108 void update_ts(ts *tstp);
1109 void SV_alloc( SV_TAB *psv, int numSeg, int struct_size );
1110 void SV_free( SV_TAB *psv );
1111 void free_sv_table( void * );
1112 void print_IMPs(void);
1113 bool flag_set( const char *flags, const char *target );
1114 void print_models(bool );
1115 float modify_param( float a, char *expr );
1116 int process_param_mod( char *pstr, char *par, char *mod );
1117 char* get_typename(int type);
1118 bool verify_flags( const char *flags, const char* given );
1119 int load_ionic_module(const char*);
1120 char *get_next_list( char *lst, char delimiter );
1121 
1122 // Functions for getting SVs in sv_init.c
1124 
1125 #include "ION_IF_sv.h"
1126 
1127 #define CHANGE_PARAM( T, P, V, F ) do { \
1128  ((T##_Params *)P)->V = modify_param( ((T##_Params *)P)->V, F ); \
1129  log_msg( _nc_logf,0, 0, " %-20s modifier: %-15s value: %g",\
1130  #V,F,(float)((T##_Params *)P)->V);} while (0)
1131 
1132 } // namespace limpet
1133 
1134 #endif
#define NDEF
definition of cell geometry
Definition: ION_IF.h:118
Basic utility structs and functions, mostly IO related.
Represents the ionic model and plug-in (IMP) data structure.
Definition: ION_IF.h:168
virtual void initialize(double dt, GlobalData_t **impdat)
Initializes lookup table and state variable tables.
Definition: ION_IF.cc:232
void rebuild_lookup_tables()
Rebuilds this IMP's lookup tables and GPU definition mirror.
Definition: ION_IF.cc:432
void tune(const char *im_par, const char *plugs, const char *plug_par)
Tunes specific IMP parameters from files.
Definition: ION_IF.cc:457
Target _target
execution target for this IMP
Definition: ION_IF.h:181
void set_parent(IonIfBase *parent)
Definition: ION_IF.cc:170
node_count_t restore_per_node(opencarp::FILE_SPEC in, node_count_t n, const node_index_t *pos, IIF_Mask_t *mask, size_t *offset, IMPinfo *impinfo, const global_node_index_t *loc2canon)
Reads in the state variables for an IMP from a per-node (format >= 3) dump.
Definition: ION_IF.cc:357
virtual void set_target(Target target)
Definition: ION_IF.cc:212
const IonType & get_type() const
Gets this IMP's model type.
Definition: ION_IF.cc:134
virtual void copy_SVs_from(IonIfBase &other, bool alloc)=0
Copies the state variables of an IMP.
char * fill_buf(char *buf, int *n, opencarp::Salt_list *l) const
Appends the state variables to a buffer.
Definition: ION_IF.cc:262
float get_dt() const
Gets the basic integration time step.
Definition: ION_IF.cc:190
int read_svs(FILE *file)
Reads state variable values for one cell from a file.
Definition: ION_IF.cc:504
bool has_lookup_tables() const
Definition: ION_IF.h:204
virtual void copy_configuration_from(IonIfBase &other)=0
Copies model configuration needed to initialize an equivalent IMP.
void for_each_sv_field(node_index_t node, const std::vector< std::pair< int, int >> &fields, Fn &&fn)
Visits each state-variable field of one node, in storage order.
Definition: ION_IF.h:505
std::vector< LUT > & tables()
Gets the array of state variables.
Definition: ION_IF.cc:202
ts _tstp
control time stepping
Definition: ION_IF.h:183
std::vector< IonIfBase * > & plugins()
Returns a vector containing the plugins of this IMP.
Definition: ION_IF.cc:174
int dump_luts(bool zipped)
Dumps array of LUTs to file.
Definition: ION_IF.cc:402
void get_sv_layout(std::vector< std::pair< int, int >> &fields) const
Describes the per-node memory layout of this IMP's state variables.
Definition: ION_IF.cc:326
void compute(node_index_t start, node_index_t end, GlobalData_t **data)
Perform ionic model computation for 1 time step.
Definition: ION_IF.cc:258
virtual ~IonIfBase()
Virtual destructor declaration.
Definition: ION_IF.cc:126
int write_svs(FILE *file, node_index_t node)
Definition: ION_IF.cc:511
size_t get_sv_per_node_size() const
Size in bytes of one node's de-interleaved state-variable record.
Definition: ION_IF.cc:334
uint64_t sv_fingerprint() const
Fingerprint of this IMP's state-variable layout.
Definition: ION_IF.cc:341
void set_moddat(uint32_t data)
Set the data flag for this IMP's modified data.
Definition: ION_IF.cc:186
void set_dt(float dt)
Sets the basic integration time step.
Definition: ION_IF.cc:194
ts & get_tstp()
Gets the time stepper.
Definition: ION_IF.cc:198
void for_each(const std::function< void(IonIfBase &)> &consumer)
Executes the consumer functions on this IMP and each of its plugins.
Definition: ION_IF.cc:526
size_t get_n_tables_d() const
Gets the size of the array returned by IonIf::tables_d.
Definition: ION_IF.cc:208
IonIfBase * parent() const
Gets the parent IMP.
Definition: ION_IF.cc:166
void destroy_luts()
Releases this IMP's lookup-table handle.
Definition: ION_IF.cc:425
void share_lookup_tables_from(const IonIfBase &other)
Shares an initialized lookup-table set with an equivalent IMP.
Definition: ION_IF.cc:449
virtual void initialize_state(double dt, GlobalData_t **impdat)
Initializes state and private workspace without constructing LUTs.
Definition: ION_IF.cc:249
Target get_target() const
Definition: ION_IF.h:381
node_count_t restore(opencarp::FILE_SPEC in, node_count_t n, const node_index_t *pos, IIF_Mask_t *mask, size_t *offset, IMPinfo *impinfo, const global_node_index_t *loc2canon)
Reads in the state variables for an IMP.
Definition: ION_IF.cc:275
uint32_t get_moddat() const
Gets the data flags for this IMP's modified data.
Definition: ION_IF.cc:182
int miifIdx
imp index within miif
Definition: ION_IF.h:180
virtual std::size_t get_sv_size() const =0
Gets the size of the structure this IMP uses for state variables.
void copy_plugins_from(IonIfBase &other)
Copies the plugins of an IMP.
Definition: ION_IF.cc:515
virtual void * get_sv_address()=0
Gets the raw address of the state variables for this IMP.
void initialize_params()
Initializes user modifiable parameters with default values defined in the respective ionic models.
Definition: ION_IF.cc:224
IonIfBase(const IonType &type, Target target, node_count_t num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructor for IonIfBase.
Definition: ION_IF.cc:109
uint32_t get_reqdat() const
Gets the data flags for this IMP's required data.
Definition: ION_IF.cc:178
node_count_t get_num_node() const
Gets the number of nodes handled by this IMP.
Definition: ION_IF.cc:138
std::size_t get_num_threads() const
Gets the number of threads used for running this IMP.
Definition: ION_IF.cc:142
LUT * tables_d() const
Gets an array of LUTs.
Definition: ION_IF.h:366
cell_geom & cgeom()
Gets the cell geometry data.
Definition: ION_IF.h:290
Utility class for handling arrays of data used by IMPs.
Definition: ION_IF.h:680
~LimpetArray()
Destroy a limpet array.
Definition: ION_IF.h:710
LimpetArray & operator=(LimpetArray &&other)
Move assignement operator.
Definition: ION_IF.h:792
LimpetArray()
Default constructor with no allocated data.
Definition: ION_IF.h:693
LimpetArray(Target target, std::size_t size)
Constructs a LimpetArray.
Definition: ION_IF.h:702
std::enable_if< std::is_void< Type >::value, std::size_t >::type get_element_size() const
Definition: ION_IF.h:746
bool is_allocated() const
Returns whether data has been allocated for this LimpetArray.
Definition: ION_IF.h:782
std::size_t size() const
Gets the sizee of the array.
Definition: ION_IF.h:771
std::enable_if<!std::is_void< Type >::value, std::size_t >::type get_element_size() const
Get the size of a single element (size of type S)
Definition: ION_IF.h:741
S * data() const
Gets a pointer to the underlying data.
Definition: ION_IF.h:758
void allocate(Target target, std::size_t size)
Allocate the array on the given target.
Definition: ION_IF.h:724
Child class of IonIfBase specialized for each ionic model type.
Definition: ION_IF.h:656
IonIf(const IonType &type, Target target, node_count_t num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructs an IonIf object.
Definition: ION_IF.h:834
PrivateTab & ion_private()
Gets the ion private LimpetArray for the current target.
Definition: ION_IF.h:886
SvTab & sv_tab()
Gets the SV LimpetArray for the current target.
Definition: ION_IF.h:873
void copy_ion_private(IonIf< T > &other, has_rosenbrock_vector_type)
Copy the ion private array from other.
Definition: ION_IF.h:1024
void copy_configuration_from(IonIfBase &other_base) override
Copy typed parameters and cell geometry from another IMP.
Definition: ION_IF.h:978
T::params_type * params() const
Gets a pointer to the parameter structure for the current target.
Definition: ION_IF.h:861
void initialize_state(double dt, GlobalData_t **impdat) override
Initializes state and private workspace without constructing LUTs.
Definition: ION_IF.h:968
void copy_ion_private(IonIf< T > &other, no_rosenbrock_type)
This function does nothing (overload of copy_ion_private(IonIf<T>&, has_rosenbrock_type)).
Definition: ION_IF.h:1059
PrivateVectorTab & ion_private_vector()
Definition: ION_IF.h:890
void initialize(double dt, GlobalData_t **impdat) override
Override of the initialization function to add the initialization of the private structures.
Definition: ION_IF.h:963
void init_ion_private(has_rosenbrock_vector_type)
Initialize private data.
Definition: ION_IF.h:1066
~IonIf()
Destroy the IMP.
Definition: ION_IF.h:845
void * get_sv_address() override
Gets the raw address of the SV array for the current target.
Definition: ION_IF.h:902
void allocate_model_data()
Allocate memory for the IMP data for the current target.
Definition: ION_IF.h:940
void copy_ion_private(IonIf< T > &other, has_rosenbrock_type)
Copy the ion private array from other.
Definition: ION_IF.h:1047
void init_ion_private(has_rosenbrock_type)
Initialize private data.
Definition: ION_IF.h:1087
void init_ion_private(no_rosenbrock_type)
Doesn't do anything.
Definition: ION_IF.h:1100
void copy_SVs_from(IonIfBase &other_base, bool alloc) override
Copy state and private variables from another IMP.
Definition: ION_IF.h:1002
std::size_t get_sv_size() const override
Gets the size of a SV structure.
Definition: ION_IF.h:911
void set_target(Target target) override
Set a new execution target for this IMP.
Definition: ION_IF.h:923
Abstract class representing an ionic model type.
Definition: ion_type.h:44
virtual size_t dlo_vector_size() const =0
Gets the vector size when using data layout optimization (DLO).
Owns the host and device representations of one IMP's lookup tables.
Definition: ION_IF.h:149
LUT * device
Definition: ION_IF.h:158
LutSet(const LutSet &)=delete
LutSet(Target target)
Definition: ION_IF.h:151
std::vector< LUT > host
Definition: ION_IF.h:157
size_t device_count
Definition: ION_IF.h:159
LutSet & operator=(const LutSet &)=delete
void(* SVputfcn)(IonIfBase &, node_index_t, int, GlobalData_t)
Definition: ion_type.h:34
char * get_typename(int type)
int process_param_mod(char *pstr, char *par, char *mod)
void SV_alloc(SV_TAB *psv, int numSeg, int struct_size)
SVputfcn getPutSV(SVgetfcn)
int load_ionic_module(const char *)
Target
enum that represents different targets to run ionic models on.
Definition: target.h:30
@ UNKNOWN
special value to handle unknown targets
Definition: target.h:32
@ N_TARGETS
a token to indicate the maximum number of targets
Definition: target.h:37
@ MLIR_CPU
vectorized CPU code generated with MLIR
Definition: target.h:34
bool flag_set(const char *flags, const char *target)
Definition: ION_IF.cc:666
SF_real GlobalData_t
Definition: limpet_types.h:12
void print_IMPs(void)
bool verify_flags(const char *flags, const char *given)
Definition: ION_IF.cc:644
GlobalData_t(* SVgetfcn)(IonIfBase &, node_index_t, int)
Definition: ion_type.h:33
void deallocate_on_target(Target target, T *ptr)
Utility function for deallocating memory on a target. See TargetAllocator.
Definition: target.h:303
void SV_free(SV_TAB *psv)
void print_models(bool)
void update_ts(ts *ptstp)
Definition: ION_IF.cc:575
opencarp::local_index_t node_count_t
Definition: limpet_types.h:14
char * get_next_list(char *lst, char delimiter)
Definition: ION_IF.cc:621
void free_sv_table(void *)
float modify_param(float a, char *expr)
char IIF_Mask_t
Definition: ion_type.h:35
opencarp::global_index_t global_node_index_t
Definition: limpet_types.h:15
opencarp::local_index_t node_index_t
Definition: limpet_types.h:13
void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
Definition: ION_IF.cc:546
V mod(const V &a, const V &b)
Definition: signals.h:35
int offset
offset into node data
Definition: ION_IF.h:138
int sz
storage required
Definition: ION_IF.h:133
char * name
IMP name.
Definition: ION_IF.h:132
int map
which plugin does this IMO match
Definition: ION_IF.h:137
IMPinfo * plug
plugins
Definition: ION_IF.h:135
bool compatible
does IM match stored IM
Definition: ION_IF.h:136
int nplug
number of plugins
Definition: ION_IF.h:134
uint64_t fingerprint
saved SV-layout fingerprint (format >= 3; 0 otherwise)
Definition: ION_IF.h:139
lookup table structure
Definition: LUT.h:31
array of stat variable structures
Definition: ION_IF.h:100
int svSize
size of structure holding SV's for a node
Definition: ION_IF.h:101
int numSeg
number of unknowns
Definition: ION_IF.h:102
void * y
Definition: ION_IF.h:103
float fr_myo
volume of myoplasm
Definition: ION_IF.h:123
float sl_i2c
convert sl-currents in uA/cm^2 to mM/L without valence
Definition: ION_IF.h:124
float SVratio
single cell surface-to-volume ratio (per um)
Definition: ION_IF.h:120
float v_cell
cell volume
Definition: ION_IF.h:121
float a_cap
capacitive cell surface
Definition: ION_IF.h:122
time constant groups
Definition: ION_IF.h:80
int update
Definition: ION_IF.h:84
float dt
Definition: ION_IF.h:81
time stepper
Definition: ION_IF.h:91
int cnt
Definition: ION_IF.h:92
int ng
Definition: ION_IF.h:93
tc_grp * tcg
Definition: ION_IF.h:94
saltatory list – memory is allocated in chunks
Definition: basics.h:44
File descriptor struct.
Definition: basics.h:120
Defines valid targets for an ionic model to run on and an allocator for allocating memory on a specif...