NEURON
mechanism.hpp
Go to the documentation of this file.
1 #pragma once
4 
5 #include <algorithm>
6 #include <cassert>
7 #include <functional>
8 #include <memory>
9 
11 struct Variable {
12  std::string name{};
13  int array_size{1};
14 };
15 namespace field {
16 /** @brief Catch-all for floating point per-instance variables in the MOD file.
17  *
18  * @todo Update the code generation so we get some hh_data = soa<hh_identifier,
19  * hh_a, hh_b, ...> type instead of fudging things this way.
20  */
21 struct FloatingPoint {
22  FloatingPoint(std::vector<Variable> var_info)
23  : m_var_info{std::move(var_info)} {}
24  /**
25  * @brief How many copies of this column should be created?
26  *
27  * Typically this is the number of different RANGE variables in a mechanism.
28  */
29  [[nodiscard]] std::size_t num_variables() const {
30  return m_var_info.size();
31  }
32 
33  [[nodiscard]] Variable const& info(std::size_t i) const {
34  return m_var_info.at(i);
35  }
36 
37  /**
38  * @brief What is the array dimension of the i-th copy of this column?
39  *
40  * Typically this is 1 for a normal RANGE variable and larger for an array RANGE variable.
41  */
42  [[nodiscard]] int array_dimension(int i) const {
43  return info(i).array_size;
44  }
45 
46  [[nodiscard]] const char* name(int i) const {
47  return info(i).name.c_str();
48  }
49 
50  using type = double;
51 
52  private:
53  std::vector<Variable> m_var_info{};
54 };
55 } // namespace field
56 
57 /**
58  * @brief Base class defining the public API of Mechanism handles.
59  * @tparam Identifier The concrete owning/non-owning identifier type.
60  *
61  * This allows the same struct-like accessors (v(), ...) to be
62  * used on all of the different types of objects that represent a single Node:
63  * - owning_handle: stable over permutations of underlying data, manages
64  * lifetime of a row in the underlying storage. Only null when in moved-from
65  * state.
66  * - handle: stable over permutations of underlying data, produces runtime error
67  * if it is dereferenced after the corresponding owning_handle has gone out of
68  * scope. Can be null.
69  */
70 template <typename Identifier>
71 struct handle_interface: handle_base<Identifier> {
73  using base_type::base_type;
74 
75  /**
76  * @brief Return the number of floating point fields accessible via fpfield.
77  */
78  [[nodiscard]] int num_fpfields() const {
79  return this->template get_tag<field::FloatingPoint>().num_variables();
80  }
81 
82  /**
83  * @brief Get the sum of array dimensions of floating point fields.
84  */
85  [[nodiscard]] int fpfields_size() const {
86  auto* const prefix_sums =
87  this->underlying_storage().template get_array_dim_prefix_sums<field::FloatingPoint>();
88  auto const num_fields = num_fpfields();
89  return prefix_sums[num_fields - 1];
90  }
91 
92  /**
93  * @brief Return the array size of the given field.
94  */
95  [[nodiscard]] int fpfield_dimension(int field_index) const {
96  if (auto const num_fields = num_fpfields(); field_index >= num_fields) {
97  throw std::runtime_error("fpfield #" + std::to_string(field_index) + " out of range (" +
98  std::to_string(num_fields) + ")");
99  }
100  auto* const array_dims =
101  this->underlying_storage().template get_array_dims<field::FloatingPoint>();
102  return array_dims[field_index];
103  }
104 
105  [[nodiscard]] field::FloatingPoint::type& fpfield(int field_index, int array_index = 0) {
106  return this->underlying_storage().fpfield(this->current_row(), field_index, array_index);
107  }
108 
110  int array_index = 0) const {
111  return this->underlying_storage().fpfield(this->current_row(), field_index, array_index);
112  }
113 
114  /** @brief Return a data_handle to a floating point value.
115  */
117  int array_index = 0) {
118  return this->underlying_storage().fpfield_handle(this->id(), field_index, array_index);
119  }
120 
121  friend std::ostream& operator<<(std::ostream& os, handle_interface const& handle) {
122  os << handle.underlying_storage().name() << '{' << handle.id() << '/'
123  << handle.underlying_storage().size();
124  auto const num = handle.num_fpfields();
125  for (auto i = 0; i < num; ++i) {
126  os << " fpfield[" << i << "]{";
127  for (auto j = 0; j < handle.fpfield_dimension(i); ++j) {
128  os << " " << handle.fpfield(i, j);
129  }
130  os << " }";
131  }
132  return os << '}';
133  }
134 };
135 } // namespace neuron::container::Mechanism
#define i
Definition: md1redef.h:19
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:200
std::string to_string(const T &obj)
size_t j
Catch-all for floating point per-instance variables in the MOD file.
Definition: mechanism.hpp:21
Variable const & info(std::size_t i) const
Definition: mechanism.hpp:33
int array_dimension(int i) const
What is the array dimension of the i-th copy of this column?
Definition: mechanism.hpp:42
std::size_t num_variables() const
How many copies of this column should be created?
Definition: mechanism.hpp:29
FloatingPoint(std::vector< Variable > var_info)
Definition: mechanism.hpp:22
Base class defining the public API of Mechanism handles.
Definition: mechanism.hpp:71
data_handle< field::FloatingPoint::type > fpfield_handle(int field_index, int array_index=0)
Return a data_handle to a floating point value.
Definition: mechanism.hpp:116
int fpfield_dimension(int field_index) const
Return the array size of the given field.
Definition: mechanism.hpp:95
friend std::ostream & operator<<(std::ostream &os, handle_interface const &handle)
Definition: mechanism.hpp:121
field::FloatingPoint::type const & fpfield(int field_index, int array_index=0) const
Definition: mechanism.hpp:109
field::FloatingPoint::type & fpfield(int field_index, int array_index=0)
Definition: mechanism.hpp:105
int num_fpfields() const
Return the number of floating point fields accessible via fpfield.
Definition: mechanism.hpp:78
int fpfields_size() const
Get the sum of array dimensions of floating point fields.
Definition: mechanism.hpp:85
Stable handle to a generic value.
Definition: data_handle.hpp:61
Struct used to index SoAoS data, such as array range variables.
Base class for neuron::container::soa<...> handles.
Definition: view_utils.hpp:34
std::size_t current_row() const
Return current offset in the underlying storage where this object lives.
Definition: view_utils.hpp:44
auto & underlying_storage()
Obtain a reference to the storage this handle refers to.
Definition: view_utils.hpp:69
non_owning_identifier_without_container id() const
Obtain a lightweight identifier of the current entry.
Definition: view_utils.hpp:54