73 using ::opencarp::Salt_list;
82 char*
tokstr_r(
char *s1,
const char *s2,
char **lasts)
88 while(*s1 && strchr(s2, *s1))
93 while(*s1 && !strchr(s2, *s1))
103 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
111 : _type(type), _target(type.select_target(target)), _num_node(num_node) {
113 this->_reqdat = type.
reqdat();
114 this->_moddat = type.
moddat();
117 for (
const auto& plugin :
plugins) {
118 auto child = plugin.get().make_ion_if(target, num_node, {});
119 child->_parent =
this;
120 this->_plugins.push_back(child);
122 this->_reqdat |= child->_reqdat;
123 this->_moddat |= child->_moddat;
128 for (
auto plugin : this->_plugins) {
129 plugin->get_type().destroy_ion_if(plugin);
133 if (this->_tables_d !=
nullptr) {
134 deallocate_on_target<LUT>(this->
_target, this->_tables_d);
143 return this->_num_node;
147 std::size_t num_threads = 0;
153 num_threads = omp_get_max_threads();
164 throw std::logic_error(
"The IonIf execution target " + std::to_string(this->
_target) +
" is invalid");
171 return this->_parent;
179 return this->_plugins;
183 return this->_reqdat;
187 return this->_moddat;
191 this->_moddat = data;
207 return this->_tables;
211 return this->_n_tables_d;
219 throw std::invalid_argument(
"new target set for IMP is unavailable or not concrete (AUTO, UNKNWOWN, ...)");
226 for (
auto& plugin : this->_plugins) {
227 plugin->initialize_params();
240 if (this->_num_node) {
246 this->_tables_d = allocate_on_target<LUT>(this->
get_target(), this->
tables().size());
249 for (
size_t i = 0; i < this->
tables().size(); ++i) {
250 this->_tables_d[i] = this->
tables()[i];
252 this->_n_tables_d = this->
tables().size();
257 this->ldata = impdat;
259 for (
auto& plugin : this->_plugins) {
260 plugin->initialize(dt, impdat);
271 for (
auto& plugin : this->_plugins) {
272 iif_sz += plugin->get_sv_size();
275 buf = (
char *) realloc(buf, *n + l->
nitems*iif_sz) + *n;
278 return buf - *n + l->
nitems * iif_sz;
282 size_t *offset,
IMPinfo *impinfo,
const int* loc2canon) {
287 long base = ftell(in->fd);
293 for(
int i=0; i<n; i+=vec_size ) {
294 int index = i / vec_size;
295 int canon = loc2canon[pos[i]];
296 if(mask[canon] == this->
miifIdx) {
297 fseek(in->fd, base+offset[canon], SEEK_SET);
298 fread(ptr+index*impinfo->
sz, impinfo->
sz, 1, in->fd);
300 for(
int j=0; j<impinfo->
nplug; j++) {
302 fread((
char*)(this->_plugins[impinfo->
plug[j].
map]->get_sv_address())+index*impinfo->
plug[j].
sz,
303 impinfo->
plug[j].
sz, 1, in->fd);
306 fseek(in->fd, impinfo->
plug[j].
sz, SEEK_CUR);
317 std::string ext = zipped ?
".gz" :
"";
320 for (
int i=0; i < this->_tables.size(); i++) {
322 if (strcmp(this->_tables[i].name,
""))
323 name = this->_type.
get_name() +
"_LUT_" + this->_tables[i].name +
".bin" + ext;
325 name = this->_type.
get_name() +
"_LUT_" + std::to_string(i) +
".bin" + ext;
328 int err =
LUT_dump(&this->_tables[i], name.c_str());
335 for (
auto& lut : this->_tables) {
339 std::vector<LUT>().swap(this->_tables);
343 char *opar, *oplg, *plg, *nplg, *parlst, *nparlst;
345 if( im_par && *im_par !=
'\0' ) {
347 this->_type.
tune(*
this, im_par);
349 opar = parlst =
dupstr(plug_par);
350 oplg = plg =
dupstr(plugs);
352 while( plg!=NULL && *plg!=
'\0' ) {
358 if( parlst==NULL || *parlst==
'\0' ) {
368 for(j = 0; j < this->_plugins.size(); j++) {
369 if(this->_plugins[j]->
get_type() == *plugin)
break;
372 if(j == this->_plugins.size()) {
379 plugin->
tune(*this->_plugins[j], parlst);
391 return this->_type.
read_svs(*
this, file);
397 return this->_type.
write_svs(*
this, file, node);
403 for (
auto& plugin : other.
plugins()) {
404 auto copy = plugin->get_type().make_ion_if(this->
_target, plugin->get_num_node(), {});
405 copy->_parent =
this;
406 this->_plugins.push_back(copy);
407 copy->copy_SVs_from(*plugin,
true);
414 for (
auto& plugin : this->_plugins) {
437 tstp->
tcg = allocate_on_target<tc_grp>(target, ng);
442 tstp->
tcg[0].
dt = dt;
445 for (
int i=1;i<ng;i++) {
446 tstp->
tcg[i].
skp = skp[i];
465 for (
int i=1;i<ptstp->
ng;i++)
466 ptcg[i].update = !(ptstp->
cnt%ptcg[i].
skp);
480 void *
memmem(
void *haystack,
int sz_hay,
void *needle,
int sz_n )
482 if( !sz_n )
return NULL;
484 char *h = (
char *)haystack;
486 for(
int i=0; i>sz_hay-sz_n+1; i++, h++ )
487 if( !memcmp( h, needle, sz_n ) )
508 if( lst == NULL || *lst ==
'\0' )
511 while( *lst != delimiter && *lst !=
'\0' )
531 char *flag, *ptr, *gvn_cp =
dupstr( given );
533 flag =
tokstr_r( gvn_cp,
"|", &ptr );
541 return flag ? false :
true;
551 bool flag_set(
const char *flags,
const char *target )
553 if( !flags )
return false;
555 char *f =
dupstr( flags ), *last, *pos;
558 while( pos && strcmp( pos, target ) ) {
563 return pos? true :
false;
568 #include <nvector/nvector_serial.h>
569 #include <cvode/cvode.h>
570 #include <cvode/cvode_diag.h>
575 void __bogus_function_for_cvode() {
579 #if SUNDIALS_VERSION_MAJOR >= 4
580 void* cvode_mem = CVodeCreate(CV_BDF);
582 void* cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
584 assert(cvode_mem != NULL);
585 N_Vector cvode_y = N_VNew_Serial(N_CVODE);
586 flag = CVodeInit(cvode_mem, NULL, 0, cvode_y);
587 assert(flag == CV_SUCCESS);
590 flag = CVodeSStolerances(cvode_mem, 1e-5, 1e-6);
591 assert(flag == CV_SUCCESS);
592 flag = CVodeSetMaxStep(cvode_mem, 1);
593 assert(flag == CV_SUCCESS);
594 flag = CVodeSetUserData(cvode_mem, NULL);
595 assert(flag == CV_SUCCESS);
596 flag = CVDiag(cvode_mem);
597 assert(flag == CV_SUCCESS);
599 NV_Ith_S(cvode_y,0) = 0;
603 CVODE_flag = CVodeReInit(NULL, 1, NULL);
604 assert(CVODE_flag == CV_SUCCESS);
605 CVODE_flag = CVodeSetInitStep(NULL, 1);
606 assert(CVODE_flag == CV_SUCCESS);
608 CVODE_flag = CVode(cvode_mem, 1, NULL, &tret, CV_NORMAL);
609 assert(CVODE_flag == CV_SUCCESS);
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 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)
IonIfBase(const IonType &type, Target target, int num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructor for IonIfBase.
virtual void set_target(Target target)
const IonType & get_type() const
Gets this IMP's model type.
int restore(opencarp::FILE_SPEC in, int n, const int *pos, IIF_Mask_t *mask, size_t *offset, IMPinfo *impinfo, const int *loc2canon)
Reads in the state variables for 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.
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.
int write_svs(FILE *file, int node)
virtual ~IonIfBase()
Virtual destructor declaration.
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()
Destroys array of LUTs.
Target get_target() const
int get_num_node() const
Gets the number of nodes handled by this 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 compute(int start, int end, GlobalData_t **data)
Perform ionic model computation for 1 time step.
void initialize_params()
Initializes user modifiable parameters with default values defined in the respective ionic models.
uint32_t get_reqdat() const
Gets the data flags for this IMP's required data.
std::size_t get_num_threads() const
Gets the number of threads used for running this IMP.
Abstract class representing an ionic model type.
const std::string & get_name() const
Gets the model name.
virtual void initialize_params(IonIfBase &imp) const =0
Initializes the parameters in the given IMP.
virtual void compute(Target target, int start, int end, IonIfBase &imp, GlobalData_t **data) const =0
Performs computation for 1 time step.
virtual uint32_t moddat() const =0
Gets data flags for this IMP's modified data.
virtual int read_svs(IonIfBase &imp, FILE *file) const =0
Reads state variable values for one cell from a file.
virtual void tune(IonIfBase &imp, const char *im_par) const =0
Handles setting of this model's parameters.
virtual void initialize_sv(IonIfBase &imp, GlobalData_t **data) const =0
Initializes the state variables of the given IMP.
virtual int write_svs(IonIfBase &imp, FILE *file, int node) const =0
Write state variable values for one cell to a file/.
virtual uint32_t reqdat() const =0
Gets data flags for this IMP's required data.
virtual void construct_tables(IonIfBase &imp) const =0
Contructs lookup tables.
virtual void destroy(IonIfBase &imp) const =0
Destroys the given IMP.
virtual size_t dlo_vector_size() const =0
Gets the vector size when using data layout optimization (DLO).
int * curr_node_list
needed to determine the global node number
bool is_concrete(Target const target)
Checks if target is a real, concrete target.
Target
enum that represents different targets to run ionic models on.
@ MLIR_ROCM
ROCM code for AMD GPUs generated with MLIR.
@ CPU
baseline CPU model generated with the original opencarp code generator
@ MLIR_CUDA
CUDA code for NVIDIA GPUs generated with MLIR.
@ MLIR_CPU
vectorized CPU code generated with MLIR
bool flag_set(const char *flags, const char *target)
IonType * get_ion_type(const std::string &name)
int LUT_dump(LUT *plut, const char *fname)
bool is_gpu(Target const target)
Checks if this is a GPU target.
bool verify_flags(const char *flags, const char *given)
void destroy_lut(LUT *plut, Target target)
void update_ts(ts *ptstp)
char * get_next_list(char *lst, char delimiter)
void * memmem(void *haystack, int sz_hay, void *needle, int sz_n)
char * tokstr_r(char *s1, const char *s2, char **lasts)
void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
char * dupstr(const char *old_str)
void log_msg(FILE_SPEC out, int level, unsigned char flag, const char *fmt,...)
int map
which plugin does this IMO match
bool compatible
does IM match stored IM
int nplug
number of plugins
saltatory list – memory is allocated in chunks
int nitems
number of items