41 #include <cuda_runtime.h>
44 #include <hip/hip_runtime.h>
57 #define M_PI 3.14159265358979323846264338327
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))
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
174 std::vector<IonIfBase*> _plugins;
187 std::shared_ptr<LutSet> _tables;
188 LUT* _tables_d =
nullptr;
189 size_t _n_tables_d = 0;
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;
201 const std::vector<sv_field>& sv_layout()
const;
259 std::vector<IonIfBase*>&
plugins();
287 #if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL
354 std::vector<LUT>&
tables();
363 #if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL
367 return this->_tables_d;
378 #if defined HAS_GPU_MODEL
488 void get_sv_layout(std::vector<std::pair<int, int>>& fields)
const;
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));
592 void tune(
const char *im_par,
const char *plugs,
const char *plug_par);
664 struct has_rosenbrock_type {};
665 struct has_rosenbrock_vector_type {};
666 struct no_rosenbrock_type {};
681 static constexpr
bool is_void = std::is_void<S>::value;
686 bool _allocated =
false;
713 if (!is_void && _allocated) {
714 deallocate_on_target<S>(this->_target, this->_data);
726 this->_target = target;
728 bool do_zero =
false;
729 this->_data = allocate_on_target<S>(this->_target, this->_size, do_zero);
730 this->_allocated =
true;
740 template<
typename Type = S>
741 typename std::enable_if<!std::is_void<Type>::value, std::size_t>::type
get_element_size()
const {
745 template<
typename Type = S>
746 typename std::enable_if<std::is_void<Type>::value, std::size_t>::type
get_element_size()
const {
759 static_assert(!is_void,
"The LimpetArray class can't be used with type 'void'");
772 static_assert(!is_void,
"The LimpetArray class can't be used with type 'void'");
783 return this->_allocated;
793 if (
this == &other) {
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;
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>;
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;
823 PrivateVectorTab _ion_private_vector;
847 if (this->_params[i] !=
nullptr) {
861 typename T::params_type *
params()
const {
887 return this->_ion_private[this->
get_target()];
892 throw std::logic_error(
"the vectorized ion private structure can only be used with the MLIR_CPU (vectorized CPU) target");
894 return this->_ion_private_vector;
903 return (
void *) this->_sv_tabs[this->
get_target()].data();
912 return sizeof(
typename T::state_type);
928 memcpy(this->
sv_tab().data(), this->_sv_tabs[old_target].data(), this->
sv_tab().size());
932 memcpy(this->
params(), this->_params[old_target],
sizeof(
typename T::params_type));
933 if (had_lookup_tables && old_target != this->
get_target())
942 if (!this->_sv_tabs[this->
get_target()].is_allocated())
945 if (!this->_ion_private[this->
get_target()].is_allocated())
948 if (!this->_ion_private_vector.is_allocated() && this->get_target() ==
Target::MLIR_CPU)
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);
980 throw std::logic_error(
"cannot copy IMP configuration between different model types");
984 memcpy(this->
params(), other.
params(),
sizeof(
typename T::params_type));
1007 throw std::logic_error(
"cannot copy SVs if both IMPs don't handle the same amount of cells");
1113 bool flag_set(
const char *flags,
const char *target );
1118 bool verify_flags(
const char *flags,
const char* given );
1125 #include "ION_IF_sv.h"
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)
#define NDEF
definition of cell geometry
Basic utility structs and functions, mostly IO related.
Represents the ionic model and plug-in (IMP) data structure.
virtual void initialize(double dt, GlobalData_t **impdat)
Initializes lookup table and state variable tables.
void rebuild_lookup_tables()
Rebuilds this IMP's lookup tables and GPU definition mirror.
void tune(const char *im_par, const char *plugs, const char *plug_par)
Tunes specific IMP parameters from files.
Target _target
execution target for this IMP
void set_parent(IonIfBase *parent)
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.
virtual void set_target(Target target)
const IonType & get_type() const
Gets this IMP's model type.
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.
float get_dt() const
Gets the basic integration time step.
int read_svs(FILE *file)
Reads state variable values for one cell from a file.
bool has_lookup_tables() const
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.
std::vector< LUT > & tables()
Gets the array of state variables.
ts _tstp
control time stepping
std::vector< IonIfBase * > & plugins()
Returns a vector containing the plugins of this IMP.
int dump_luts(bool zipped)
Dumps array of LUTs to file.
void get_sv_layout(std::vector< std::pair< int, int >> &fields) const
Describes the per-node memory layout of this IMP's state variables.
void compute(node_index_t start, node_index_t end, GlobalData_t **data)
Perform ionic model computation for 1 time step.
virtual ~IonIfBase()
Virtual destructor declaration.
int write_svs(FILE *file, node_index_t node)
size_t get_sv_per_node_size() const
Size in bytes of one node's de-interleaved state-variable record.
uint64_t sv_fingerprint() const
Fingerprint of this IMP's state-variable layout.
void set_moddat(uint32_t data)
Set the data flag for this IMP's modified data.
void set_dt(float dt)
Sets the basic integration time step.
ts & get_tstp()
Gets the time stepper.
void for_each(const std::function< void(IonIfBase &)> &consumer)
Executes the consumer functions on this IMP and each of its plugins.
size_t get_n_tables_d() const
Gets the size of the array returned by IonIf::tables_d.
IonIfBase * parent() const
Gets the parent IMP.
void destroy_luts()
Releases this IMP's lookup-table handle.
void share_lookup_tables_from(const IonIfBase &other)
Shares an initialized lookup-table set with an equivalent IMP.
virtual void initialize_state(double dt, GlobalData_t **impdat)
Initializes state and private workspace without constructing LUTs.
Target get_target() const
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.
uint32_t get_moddat() const
Gets the data flags for this IMP's modified data.
int miifIdx
imp index within miif
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.
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.
IonIfBase(const IonType &type, Target target, node_count_t num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructor for IonIfBase.
uint32_t get_reqdat() const
Gets the data flags for this IMP's required data.
node_count_t get_num_node() const
Gets the number of nodes handled by this IMP.
std::size_t get_num_threads() const
Gets the number of threads used for running this IMP.
LUT * tables_d() const
Gets an array of LUTs.
cell_geom & cgeom()
Gets the cell geometry data.
Utility class for handling arrays of data used by IMPs.
~LimpetArray()
Destroy a limpet array.
LimpetArray & operator=(LimpetArray &&other)
Move assignement operator.
LimpetArray()
Default constructor with no allocated data.
LimpetArray(Target target, std::size_t size)
Constructs a LimpetArray.
std::enable_if< std::is_void< Type >::value, std::size_t >::type get_element_size() const
bool is_allocated() const
Returns whether data has been allocated for this LimpetArray.
std::size_t size() const
Gets the sizee of the array.
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)
S * data() const
Gets a pointer to the underlying data.
void allocate(Target target, std::size_t size)
Allocate the array on the given target.
Child class of IonIfBase specialized for each ionic model type.
IonIf(const IonType &type, Target target, node_count_t num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructs an IonIf object.
PrivateTab & ion_private()
Gets the ion private LimpetArray for the current target.
SvTab & sv_tab()
Gets the SV LimpetArray for the current target.
void copy_ion_private(IonIf< T > &other, has_rosenbrock_vector_type)
Copy the ion private array from other.
void copy_configuration_from(IonIfBase &other_base) override
Copy typed parameters and cell geometry from another IMP.
T::params_type * params() const
Gets a pointer to the parameter structure for the current target.
void initialize_state(double dt, GlobalData_t **impdat) override
Initializes state and private workspace without constructing LUTs.
void copy_ion_private(IonIf< T > &other, no_rosenbrock_type)
This function does nothing (overload of copy_ion_private(IonIf<T>&, has_rosenbrock_type)).
PrivateVectorTab & ion_private_vector()
void initialize(double dt, GlobalData_t **impdat) override
Override of the initialization function to add the initialization of the private structures.
void init_ion_private(has_rosenbrock_vector_type)
Initialize private data.
void * get_sv_address() override
Gets the raw address of the SV array for the current target.
void allocate_model_data()
Allocate memory for the IMP data for the current target.
void copy_ion_private(IonIf< T > &other, has_rosenbrock_type)
Copy the ion private array from other.
void init_ion_private(has_rosenbrock_type)
Initialize private data.
void init_ion_private(no_rosenbrock_type)
Doesn't do anything.
void copy_SVs_from(IonIfBase &other_base, bool alloc) override
Copy state and private variables from another IMP.
std::size_t get_sv_size() const override
Gets the size of a SV structure.
void set_target(Target target) override
Set a new execution target for this IMP.
Abstract class representing an ionic model type.
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.
LutSet(const LutSet &)=delete
LutSet & operator=(const LutSet &)=delete
void(* SVputfcn)(IonIfBase &, node_index_t, int, GlobalData_t)
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.
@ UNKNOWN
special value to handle unknown targets
@ N_TARGETS
a token to indicate the maximum number of targets
@ MLIR_CPU
vectorized CPU code generated with MLIR
bool flag_set(const char *flags, const char *target)
bool verify_flags(const char *flags, const char *given)
GlobalData_t(* SVgetfcn)(IonIfBase &, node_index_t, int)
void deallocate_on_target(Target target, T *ptr)
Utility function for deallocating memory on a target. See TargetAllocator.
void SV_free(SV_TAB *psv)
void update_ts(ts *ptstp)
opencarp::local_index_t node_count_t
char * get_next_list(char *lst, char delimiter)
void free_sv_table(void *)
float modify_param(float a, char *expr)
opencarp::global_index_t global_node_index_t
opencarp::local_index_t node_index_t
void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
V mod(const V &a, const V &b)
int offset
offset into node data
int map
which plugin does this IMO match
bool compatible
does IM match stored IM
int nplug
number of plugins
uint64_t fingerprint
saved SV-layout fingerprint (format >= 3; 0 otherwise)
array of stat variable structures
int svSize
size of structure holding SV's for a node
int numSeg
number of unknowns
float fr_myo
volume of myoplasm
float sl_i2c
convert sl-currents in uA/cm^2 to mM/L without valence
float SVratio
single cell surface-to-volume ratio (per um)
float a_cap
capacitive cell surface
saltatory list – memory is allocated in chunks
Defines valid targets for an ionic model to run on and an allocator for allocating memory on a specif...