69 #include <nvector/nvector_serial.h> 70 #include <cvode/cvode.h> 71 #include <cvode/cvode_diag.h> 79 using ::opencarp::Salt_list;
88 char*
tokstr_r(
char *s1,
const char *s2,
char **lasts)
94 while(*s1 && strchr(s2, *s1))
99 while(*s1 && !strchr(s2, *s1))
109 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 117 : _type(type), _target(type.select_target(target)), _num_node(num_node) {
119 this->_reqdat = type.
reqdat();
120 this->_moddat = type.
moddat();
123 for (
const auto& plugin :
plugins) {
124 auto child = plugin.get().make_ion_if(target, num_node, {});
125 child->_parent =
this;
126 this->_plugins.push_back(child);
128 this->_reqdat |= child->_reqdat;
129 this->_moddat |= child->_moddat;
134 for (
auto plugin : this->_plugins) {
135 plugin->get_type().destroy_ion_if(plugin);
139 if (this->_tables_d !=
nullptr) {
140 deallocate_on_target<LUT>(this->
_target, this->_tables_d);
149 return this->_num_node;
153 std::size_t num_threads = 0;
159 num_threads = omp_get_max_threads();
170 throw std::logic_error(
"The IonIf execution target " + std::to_string(this->
_target) +
" is invalid");
177 return this->_parent;
185 return this->_plugins;
189 return this->_reqdat;
193 return this->_moddat;
197 this->_moddat = data;
213 return this->_tables;
217 return this->_n_tables_d;
225 throw std::invalid_argument(
"new target set for IMP is unavailable or not concrete (AUTO, UNKNWOWN, ...)");
232 for (
auto& plugin : this->_plugins) {
233 plugin->initialize_params();
246 if (this->_num_node) {
252 this->_tables_d = allocate_on_target<LUT>(this->
get_target(), this->
tables().size());
255 for (
size_t i = 0; i < this->
tables().size(); ++i) {
256 this->_tables_d[i] = this->
tables()[i];
258 this->_n_tables_d = this->
tables().size();
263 this->ldata = impdat;
265 for (
auto& plugin : this->_plugins) {
266 plugin->initialize(dt, impdat);
277 for (
auto& plugin : this->_plugins) {
278 iif_sz += plugin->get_sv_size();
281 buf = (
char *) realloc(buf, *n + l->
nitems*iif_sz) + *n;
284 return buf - *n + l->
nitems * iif_sz;
288 size_t *offset,
IMPinfo *impinfo,
const int* loc2canon) {
293 long base = ftell(in->fd);
299 for(
int i=0; i<n; i+=vec_size ) {
300 int index = i / vec_size;
301 int canon = loc2canon[pos[i]];
302 if(mask[canon] == this->
miifIdx) {
303 fseek(in->fd, base+offset[canon], SEEK_SET);
304 fread(ptr+index*impinfo->
sz, impinfo->
sz, 1, in->fd);
306 for(
int j=0; j<impinfo->
nplug; j++) {
308 fread((
char*)(this->_plugins[impinfo->
plug[j].
map]->get_sv_address())+index*impinfo->
plug[j].
sz,
309 impinfo->
plug[j].
sz, 1, in->fd);
312 fseek(in->fd, impinfo->
plug[j].
sz, SEEK_CUR);
323 std::string ext = zipped ?
".gz" :
"";
326 for (
int i=0; i < this->_tables.size(); i++) {
328 if (strcmp(this->_tables[i].name,
""))
329 name = this->_type.
get_name() +
"_LUT_" + this->_tables[i].name +
".bin" + ext;
331 name = this->_type.
get_name() +
"_LUT_" + std::to_string(i) +
".bin" + ext;
334 int err =
LUT_dump(&this->_tables[i], name.c_str());
341 for (
auto& lut : this->_tables) {
345 std::vector<LUT>().swap(this->_tables);
349 char *opar, *oplg, *plg, *nplg, *parlst, *nparlst;
351 if( im_par && *im_par !=
'\0' ) {
352 log_msg( _nc_logf, 0, 0,
"Ionic model: %s", this->_type.
get_name().c_str());
353 this->_type.
tune(*
this, im_par);
355 opar = parlst =
dupstr(plug_par);
356 oplg = plg =
dupstr(plugs);
358 while( plg!=NULL && *plg!=
'\0' ) {
362 log_msg( _nc_logf, 0, 0,
"Plug-in: %s", plg );
364 if( parlst==NULL || *parlst==
'\0' ) {
374 for(j = 0; j < this->_plugins.size(); j++) {
375 if(this->_plugins[j]->
get_type() == *plugin)
break;
378 if(j == this->_plugins.size()) {
379 log_msg( _nc_logf, 2, 0,
"Plugin %s not used with IM", plg );
385 plugin->
tune(*this->_plugins[j], parlst);
397 return this->_type.
read_svs(*
this, file);
403 return this->_type.
write_svs(*
this, file, node);
409 for (
auto& plugin : other.
plugins()) {
410 auto copy = plugin->get_type().make_ion_if(this->
_target, plugin->get_num_node(), {});
411 copy->_parent =
this;
412 this->_plugins.push_back(copy);
413 copy->copy_SVs_from(*plugin,
true);
420 for (
auto& plugin : this->_plugins) {
443 tstp->
tcg = allocate_on_target<tc_grp>(target, ng);
448 tstp->
tcg[0].
dt = dt;
451 for (
int i=1;i<ng;i++) {
452 tstp->
tcg[i].
skp = skp[i];
471 for (
int i=1;i<ptstp->
ng;i++)
472 ptcg[i].update = !(ptstp->
cnt%ptcg[i].
skp);
486 void *
memmem(
void *haystack,
int sz_hay,
void *needle,
int sz_n )
488 if( !sz_n )
return NULL;
490 char *h = (
char *)haystack;
492 for(
int i=0; i>sz_hay-sz_n+1; i++, h++ )
493 if( !memcmp( h, needle, sz_n ) )
514 if( lst == NULL || *lst ==
'\0' )
517 while( *lst != delimiter && *lst !=
'\0' )
537 char *flag, *ptr, *gvn_cp =
dupstr( given );
539 flag =
tokstr_r( gvn_cp,
"|", &ptr );
547 return flag ? false :
true;
557 bool flag_set(
const char *flags,
const char *target )
559 if( !flags )
return false;
561 char *f =
dupstr( flags ), *last, *pos;
564 while( pos && strcmp( pos, target ) ) {
569 return pos? true :
false;
577 void __bogus_function_for_cvode() {
581 #if SUNDIALS_VERSION_MAJOR < 4 582 void* cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
583 #elif SUNDIALS_VERSION_MAJOR < 6 584 void* cvode_mem = CVodeCreate(CV_BDF);
585 #elif SUNDIALS_VERSION_MAJOR < 7 587 MPI_Comm comm = PETSC_COMM_WORLD;
588 if( SUNContext_Create(&comm, &sunctx )<0 ){
591 void* cvode_mem = CVodeCreate(CV_BDF, sunctx);
592 #else // version from 7.0.0 594 SUNComm comm = PETSC_COMM_WORLD;
595 if( SUNContext_Create( comm, &sunctx )<0 ){
598 void* cvode_mem = CVodeCreate(CV_BDF, sunctx);
600 assert(cvode_mem != NULL);
601 #if SUNDIALS_VERSION_MAJOR >= 6 602 N_Vector cvode_y = N_VNew_Serial(N_CVODE, sunctx);
604 N_Vector cvode_y = N_VNew_Serial(N_CVODE);
606 flag = CVodeInit(cvode_mem, NULL, 0, cvode_y);
607 assert(flag == CV_SUCCESS);
610 flag = CVodeSStolerances(cvode_mem, 1e-5, 1e-6);
611 assert(flag == CV_SUCCESS);
612 flag = CVodeSetMaxStep(cvode_mem, 1);
613 assert(flag == CV_SUCCESS);
614 flag = CVodeSetUserData(cvode_mem, NULL);
615 assert(flag == CV_SUCCESS);
616 flag = CVDiag(cvode_mem);
617 assert(flag == CV_SUCCESS);
619 NV_Ith_S(cvode_y,0) = 0;
623 CVODE_flag = CVodeReInit(NULL, 1, NULL);
624 assert(CVODE_flag == CV_SUCCESS);
625 CVODE_flag = CVodeSetInitStep(NULL, 1);
626 assert(CVODE_flag == CV_SUCCESS);
627 #if SUNDIALS_VERSION_MAJOR >= 7 632 CVODE_flag = CVode(cvode_mem, 1, NULL, &tret, CV_NORMAL);
633 assert(CVODE_flag == CV_SUCCESS);
Target _target
execution target for this IMP
float get_dt() const
Gets the basic integration time step.
const std::string & get_name() const
Gets the model name.
bool compatible
does IM match stored IM
char * dupstr(const char *old_str)
ts _tstp
control time stepping
virtual void initialize_sv(IonIfBase &imp, GlobalData_t **data) const =0
Initializes the state variables of the given IMP.
int nplug
number of plugins
const IonType & get_type() const
Gets this IMP's model type.
IonIfBase * parent() const
Gets the parent IMP.
vectorized CPU code generated with MLIR
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.
uint32_t get_reqdat() const
Gets the data flags for this IMP's required data.
virtual void initialize_params(IonIfBase &imp) const =0
Initializes the parameters in 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/.
void destroy_lut(LUT *plut, Target target)
virtual int read_svs(IonIfBase &imp, FILE *file) const =0
Reads state variable values for one cell from a file.
int read_svs(FILE *file)
Reads state variable values for one cell from a file.
virtual std::size_t get_sv_size() const =0
Gets the size of the structure this IMP uses for state variables.
void set_parent(IonIfBase *parent)
Target get_target() const
int map
which plugin does this IMO match
void set_moddat(uint32_t data)
Set the data flag for this IMP's modified data.
bool is_gpu(Target const target)
Checks if this is a GPU target.
std::size_t get_num_threads() const
Gets the number of threads used for running this IMP.
virtual void destroy(IonIfBase &imp) const =0
Destroys the given IMP.
virtual uint32_t moddat() const =0
Gets data flags for this IMP's modified data.
IonIfBase(const IonType &type, Target target, int num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructor for IonIfBase.
Represents the ionic model and plug-in (IMP) data structure.
IonType * get_ion_type(const std::string &name)
virtual void tune(IonIfBase &imp, const char *im_par) const =0
Handles setting of this model's parameters.
void compute(int start, int end, GlobalData_t **data)
Perform ionic model computation for 1 time step.
virtual size_t dlo_vector_size() const =0
Gets the vector size when using data layout optimization (DLO).
void destroy_luts()
Destroys array of LUTs.
virtual uint32_t reqdat() const =0
Gets data flags for this IMP's required data.
char * get_next_list(char *lst, char delimiter)
virtual void construct_tables(IonIfBase &imp) const =0
Contructs lookup tables.
int LUT_dump(LUT *plut, const char *fname)
void tune(const char *im_par, const char *plugs, const char *plug_par)
Tunes specific IMP parameters from files.
ts & get_tstp()
Gets the time stepper.
char * tokstr_r(char *s1, const char *s2, char **lasts)
bool is_concrete(Target const target)
Checks if target is a real, concrete target.
virtual void initialize(double dt, GlobalData_t **impdat)
Initializes lookup table and state variable tables.
bool flag_set(const char *flags, const char *target)
size_t get_n_tables_d() const
Gets the size of the array returned by IonIf::tables_d.
void for_each(const std::function< void(IonIfBase &)> &consumer)
Executes the consumer functions on this IMP and each of its plugins.
virtual void set_target(Target target)
baseline CPU model generated with the original opencarp code generator
void log_msg(FILE_SPEC out, int level, unsigned char flag, const char *fmt,...)
int nitems
number of items
int get_num_node() const
Gets the number of nodes handled by this IMP.
CUDA code for NVIDIA GPUs generated with MLIR.
std::vector< IonIfBase * > & plugins()
Returns a vector containing the plugins of this IMP.
int write_svs(FILE *file, int node)
void update_ts(ts *ptstp)
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...
int * curr_node_list
needed to determine the global node number
Target
enum that represents different targets to run ionic models on.
int dump_luts(bool zipped)
Dumps array of LUTs to file.
bool verify_flags(const char *flags, const char *given)
saltatory list – memory is allocated in chunks
virtual ~IonIfBase()
Virtual destructor declaration.
void copy_plugins_from(IonIfBase &other)
Copies the plugins of an IMP.
void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
std::vector< LUT > & tables()
Gets the array of state variables.
char * fill_buf(char *buf, int *n, opencarp::Salt_list *l) const
Appends the state variables to a buffer.
virtual void compute(Target target, int start, int end, IonIfBase &imp, GlobalData_t **data) const =0
Performs computation for 1 time step.
Abstract class representing an ionic model type.
int miifIdx
imp index within miif
void * memmem(void *haystack, int sz_hay, void *needle, int sz_n)
uint32_t get_moddat() const
Gets the data flags for this IMP's modified data.
ROCM code for AMD GPUs generated with MLIR.
void set_dt(float dt)
Sets the basic integration time step.