35 #include <cuda_runtime.h> 38 #include <hip/hip_runtime.h> 50 #ifndef M_PI //C99 does not define M_PI 51 #define M_PI 3.14159265358979323846264338327 55 #define heav(x) ( (x)<0 ? 0 : 1) 56 #define sign(x) ( (x)<0 ? -1 : 1 ) 57 #define square(x) ((x)*(x)) 58 #define cube(x) ((x)*(x)*(x)) 61 #define MPI_RESTORE_IMP_POLL_BUFSIZE_TAG 10 62 #define MPI_RESTORE_IMP_SNDRCV_BUFFER_TAG 11 63 #define MPI_DUMP_IMP_POLL_BUFSIZE_TAG 20 64 #define MPI_DUMP_IMP_SNDRCV_BUFFER_TAG 21 65 #define MPI_DUMP_SVS_POLL_BUFSIZE_TAG 30 66 #define MPI_DUMP_SVS_SNDRCV_BUFFER_TAG 31 144 std::vector<IonIfBase*> _plugins;
157 std::vector<LUT> _tables;
158 LUT * _tables_d =
nullptr;
159 size_t _n_tables_d = 0;
172 IonIfBase(
const IonType& type,
Target target,
int num_node,
const std::vector<std::reference_wrapper<IonType>>& plugins);
185 const IonType& get_type()
const;
192 int get_num_node()
const;
199 std::size_t get_num_threads()
const;
216 std::vector<IonIfBase*>& plugins();
223 uint32_t get_reqdat()
const;
230 uint32_t get_moddat()
const;
237 void set_moddat(uint32_t data);
244 #if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL 256 float get_dt()
const;
263 void set_dt(
float dt);
282 virtual void *get_sv_address() = 0;
290 virtual std::size_t get_sv_size()
const = 0;
311 std::vector<LUT>& tables();
320 #if defined HAS_CUDA_MODEL || defined HAS_ROCM_MODEL 324 return this->_tables_d;
333 size_t get_n_tables_d()
const;
335 #if defined HAS_GPU_MODEL 339 return this->_target;
342 virtual void set_target(
Target target);
348 void initialize_params();
361 virtual void initialize(
double dt,
GlobalData_t **impdat);
401 size_t *offset,
IMPinfo *impinfo,
const int* loc2canon);
410 int dump_luts(
bool zipped);
443 void tune(
const char *im_par,
const char *plugs,
const char *plug_par);
452 int read_svs(FILE* file);
454 int write_svs(FILE* file,
int node);
465 virtual void copy_SVs_from(
IonIfBase& other,
bool alloc) = 0;
475 void copy_plugins_from(
IonIfBase& other);
483 void for_each(
const std::function<
void(
IonIfBase&)>& consumer);
505 struct has_rosenbrock_type {};
506 struct has_rosenbrock_vector_type {};
507 struct no_rosenbrock_type {};
522 static constexpr
bool is_void = std::is_void<S>::value;
527 bool _allocated =
false;
545 this->allocate(target, size);
554 if (!is_void && _allocated) {
555 deallocate_on_target<S>(this->_target, this->_data);
567 this->_target = target;
569 bool do_zero =
false;
570 this->_data = allocate_on_target<S>(this->_target, this->_size, do_zero);
571 this->_allocated =
true;
581 template<
typename Type = S>
582 typename std::enable_if<!std::is_void<Type>::value, std::size_t>::type
get_element_size()
const {
586 template<
typename Type = S>
587 typename std::enable_if<std::is_void<Type>::value, std::size_t>::type
get_element_size()
const {
600 static_assert(!is_void,
"The LimpetArray class can't be used with type 'void'");
613 static_assert(!is_void,
"The LimpetArray class can't be used with type 'void'");
624 return this->_allocated;
634 if (
this == &other) {
637 this->_target = other._target;
638 this->_data = other._data;
639 this->_size = other._size;
640 if (other._allocated) {
641 this->_allocated =
true;
642 other._allocated =
false;
658 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;
676 std::vector<std::reference_wrapper<IonType>>& plugins) :
IonIfBase(type,
677 target, num_node, plugins) {
678 this->allocate_model_data();
688 if (this->_params[i] !=
nullptr) {
702 typename T::params_type *
params()
const {
703 return this->_params[this->get_target()];
715 return this->_sv_tabs[this->get_target()];
728 return this->_ion_private[this->get_target()];
733 throw std::logic_error(
"the vectorized ion private structure can only be used with the MLIR_CPU (vectorized CPU) target");
735 return this->_ion_private_vector;
744 return (
void *) this->_sv_tabs[this->get_target()].
data();
753 return sizeof(
typename T::state_type);
765 Target old_target = this->get_target();
767 this->allocate_model_data();
768 memcpy(this->sv_tab().data(), this->_sv_tabs[old_target].data(), this->sv_tab().size());
772 memcpy(this->params(), this->_params[old_target],
sizeof(
typename T::params_type));
779 std::size_t vec_size = this->get_type().dlo_vector_size();
780 if (!this->_sv_tabs[this->get_target()].is_allocated())
781 this->_sv_tabs[this->get_target()] =
782 SvTab(this->get_target(), (this->get_num_node() + vec_size - 1) / vec_size);
783 if (!this->_ion_private[this->get_target()].is_allocated())
784 this->_ion_private[this->get_target()] =
PrivateTab(this->get_target(), this->get_num_threads());
787 this->_ion_private_vector =
PrivateVectorTab(this->get_target(), this->get_num_threads());
788 if (this->_params[this->get_target()] ==
nullptr)
789 this->_params[this->get_target()] = allocate_on_target<typename T::params_type>(this->get_target(), 1,
true);
803 this->init_ion_private(rosenbrock_usage {});
825 throw std::logic_error(
"cannot copy SVs if both IMPs don't handle the same amount of cells");
828 memcpy(this->sv_tab().data(), other.
sv_tab().data(),
sizeof(
typename T::state_type) * other.
sv_tab().size());
830 this->copy_ion_private(other, rosenbrock_usage {});
831 memcpy(this->get_tstp().tcg, other.
get_tstp().tcg, tcg_size);
847 memcpy(this->ion_private().data(), other.
ion_private().data(),
sizeof(
typename T::private_type) * other.
ion_private().size());
860 memcpy(this->ion_private().data(), other.
ion_private().data(),
sizeof(
typename T::private_type) * other.
ion_private().size());
878 for (std::size_t i = 0; i < this->ion_private_vector().size(); ++i) {
879 this->ion_private_vector().data()[i].node_number = 0;
880 this->ion_private_vector().data()[i].IF =
this;
884 for (std::size_t i = 0; i < this->ion_private().size(); ++i) {
885 this->ion_private().data()[i].node_number = 0;
886 this->ion_private().data()[i].IF =
this;
897 for (std::size_t i = 0; i < this->ion_private().size(); ++i) {
898 this->ion_private().data()[i].node_number = 0;
899 this->ion_private().data()[i].IF =
this;
922 bool flag_set(
const char *flags,
const char *target );
927 bool verify_flags(
const char *flags,
const char* given );
934 #include "ION_IF_sv.h" 936 #define CHANGE_PARAM( T, P, V, F ) do { \ 937 ((T##_Params *)P)->V = modify_param( ((T##_Params *)P)->V, F ); \ 938 log_msg( _nc_logf,0, 0, " %-20s modifier: %-15s value: %g",\ 939 #V,F,(float)((T##_Params *)P)->V);} while (0) Target _target
execution target for this IMP
GlobalData_t(* SVgetfcn)(IonIfBase &, int, int)
char * get_typename(int type)
std::size_t get_sv_size() const override
Gets the size of a SV structure.
Utility class for handling arrays of data used by IMPs.
void initialize(double dt, GlobalData_t **impdat) override
Override of the initialization function to add the initialization of the private structures.
int numSeg
number of unknowns
bool compatible
does IM match stored IM
LimpetArray()
Default constructor with no allocated data.
PrivateVectorTab & ion_private_vector()
ts _tstp
control time stepping
#define NDEF
definition of cell geometry
void copy_SVs_from(IonIfBase &other_base, bool alloc) override
Copy state and private variables from another IMP.
int nplug
number of plugins
T::params_type * params() const
Gets a pointer to the parameter structure for the current target.
int process_param_mod(char *pstr, char *par, char *mod)
Child class of IonIfBase specialized for each ionic model type.
void copy_ion_private(IonIf< T > &other, no_rosenbrock_type)
This function does nothing (overload of copy_ion_private(IonIf<T>&, has_rosenbrock_type)).
float modify_param(float a, char *expr)
vectorized CPU code generated with MLIR
void(* SVputfcn)(IonIfBase &, int, int, GlobalData_t)
std::enable_if< std::is_void< Type >::value, std::size_t >::type get_element_size() const
void init_ion_private(no_rosenbrock_type)
Doesn't do anything.
SVputfcn getPutSV(SVgetfcn)
Target get_target() const
int map
which plugin does this IMO match
array of stat variable structures
void SV_alloc(SV_TAB *psv, int numSeg, int struct_size)
V mod(const V &a, const V &b)
~LimpetArray()
Destroy a limpet array.
void free_sv_table(void *)
void init_ion_private(has_rosenbrock_vector_type)
Initialize private data.
special value to handle unknown targets
Represents the ionic model and plug-in (IMP) data structure.
LimpetArray & operator=(LimpetArray &&other)
Move assignement operator.
bool is_allocated() const
Returns whether data has been allocated for this LimpetArray.
void init_ion_private(has_rosenbrock_type)
Initialize private data.
cell_geom & cgeom()
Gets the cell geometry data.
int svSize
size of structure holding SV's for a node
char * get_next_list(char *lst, char delimiter)
void copy_ion_private(IonIf< T > &other, has_rosenbrock_type)
Copy the ion private array from other.
void set_target(Target target) override
Set a new execution target for this IMP.
a token to indicate the maximum number of targets
ts & get_tstp()
Gets the time stepper.
LimpetArray(Target target, std::size_t size)
Constructs a LimpetArray.
virtual void initialize(double dt, GlobalData_t **impdat)
Initializes lookup table and state variable tables.
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)
bool flag_set(const char *flags, const char *target)
PrivateTab & ion_private()
Gets the ion private LimpetArray for the current target.
S * data() const
Gets a pointer to the underlying data.
int offset
offset into node data
virtual void set_target(Target target)
Defines valid targets for an ionic model to run on and an allocator for allocating memory on a specif...
int get_num_node() const
Gets the number of nodes handled by this IMP.
SvTab & sv_tab()
Gets the SV LimpetArray for the current target.
void update_ts(ts *ptstp)
void allocate(Target target, std::size_t size)
Allocate the array on the given target.
std::size_t size() const
Gets the sizee of the array.
Target
enum that represents different targets to run ionic models on.
bool verify_flags(const char *flags, const char *given)
saltatory list – memory is allocated in chunks
int load_ionic_module(const char *)
void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
Abstract class representing an ionic model type.
int miifIdx
imp index within miif
LUT * tables_d() const
Gets an array of LUTs.
Basic utility structs and functions, mostly IO related.
void copy_ion_private(IonIf< T > &other, has_rosenbrock_vector_type)
Copy the ion private array from other.
void SV_free(SV_TAB *psv)
void deallocate_on_target(Target target, T *ptr)
Utility function for deallocating memory on a target. See TargetAllocator.
void allocate_model_data()
Allocate memory for the IMP data for the current target.
void * get_sv_address() override
Gets the raw address of the SV array for the current target.
IonIf(const IonType &type, Target target, int num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructs an IonIf object.