1 /*
2 * model.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #ifndef MODEL_H
24 #define MODEL_H
25
26 // C++ includes:
27 #include <new>
28 #include <string>
29 #include <vector>
30
31 // Includes from libnestutil:
32 #include "allocator.h"
33
34 // Includes from nestkernel:
35 #include "node.h"
36
37 // Includes from sli:
38 #include "dictutils.h"
39
40 namespace nest
41 {
42 class TimeConverter;
43
44 /**
45 * Base class for all Models.
46 * Each Node class is associated with a corresponding Model
47 * class. The Model class is responsible for the creation and class
48 * wide parametrisation of its associated Node objects.
49 *
50 * class Model manages the thread-sorted memory pool of the model.
51 * The default constructor uses one thread as default. Use set_threads() to
52 * use more than one thread.
53 * @ingroup user_interface
54 * @see Node
55 */
56 class Model
57 {
58 public:
59 Model( const std::string& name );
Model(const Model & m)60 Model( const Model& m )
61 : name_( m.name_ )
62 , type_id_( m.type_id_ )
63 , memory_( m.memory_ )
64 {
65 }
66
~Model()67 virtual ~Model()
68 {
69 }
70
71 /**
72 * Create clone with new name.
73 */
74 virtual Model* clone( const std::string& ) const = 0;
75
76 /**
77 * Set number of threads based on number set in network.
78 * As long as no nodes of the model have been allocated, the number
79 * of threads may be changed.
80 * @note Requires that network pointer in NestModule is initialized.
81 */
82 void set_threads();
83
84 /**
85 * Allocate new Node and return its pointer.
86 * allocate() is not const, because it
87 * is allowed to modify the Model object for
88 * 'administrative' purposes.
89 */
90 Node* allocate( thread t );
91
92 void free( thread t, Node* );
93
94 /**
95 * Deletes all nodes which belong to this model.
96 */
97
98 void clear();
99
100 /**
101 * Reserve memory for at least n additional Nodes.
102 * A number of memory managers work more efficiently if they have
103 * an idea about the number of Nodes to be allocated.
104 * This function prepares the memory manager for the subsequent
105 * allocation of n additional Nodes.
106 * @param t Thread for which the Nodes are reserved.
107 * @param n Number of Nodes to be allocated.
108 */
109 void reserve_additional( thread t, size_t n );
110
111 /**
112 * Return name of the Model.
113 * This function returns the name of the Model as C++ string. The
114 * name is defined by the constructor. The result is identical to the value
115 * of Node::get_name();
116 * @see Model::Model()
117 * @see Node::get_name()
118 */
119 std::string get_name() const;
120
121 /**
122 * Return the available memory. The result is given in number of elements,
123 * not in bytes.
124 * Note that this function reports a sum over all threads.
125 */
126 size_t mem_available();
127
128 /**
129 * Return the memory capacity. The result is given in number of elements,
130 * not in bytes.
131 * Note that this function reports a sum over all threads.
132 */
133 size_t mem_capacity();
134
135 virtual bool has_proxies() = 0;
136 virtual bool one_node_per_process() = 0;
137 virtual bool is_off_grid() = 0;
138 virtual void calibrate_time( const TimeConverter& tc ) = 0;
139
140 /**
141 * Change properties of the prototype node according to the
142 * entries in the dictionary.
143 * @param d Dictionary with named parameter settings.
144 * @ingroup status_interface
145 */
146 void set_status( DictionaryDatum );
147
148 /**
149 * Export properties of the prototype node by setting
150 * entries in the status dictionary.
151 * @param d Dictionary.
152 * @ingroup status_interface
153 */
154 DictionaryDatum get_status( void );
155
156 virtual port send_test_event( Node&, rport, synindex, bool ) = 0;
157
158 virtual void sends_secondary_event( GapJunctionEvent& ge ) = 0;
159 virtual void sends_secondary_event( InstantaneousRateConnectionEvent& re ) = 0;
160 virtual void sends_secondary_event( DiffusionConnectionEvent& de ) = 0;
161 virtual void sends_secondary_event( DelayedRateConnectionEvent& re ) = 0;
162
163 /**
164 * Check what type of signal this model is sending.
165 * Required so that proxynode can formward this call
166 * to model that in turn delegates the call to the underlying
167 * prototype.
168 */
169 virtual SignalType sends_signal() const = 0;
170
171 /**
172 * Return the size of the prototype.
173 */
174 virtual size_t get_element_size() const = 0;
175
176 /**
177 * Return const reference to the prototype.
178 */
179 virtual Node const& get_prototype( void ) const = 0;
180
181 /**
182 * Set the model id on the prototype.
183 */
184 virtual void set_model_id( int ) = 0;
185
186 /**
187 * Get the model id from the prototype.
188 */
189 virtual int get_model_id() = 0;
190
191 /**
192 * Issue deprecation warning on first call if model is deprecated.
193 *
194 * @param calling function
195 */
196 virtual void deprecation_warning( const std::string& ) = 0;
197
198 /**
199 * Set the model id on the prototype.
200 */
201 void
set_type_id(index id)202 set_type_id( index id )
203 {
204 type_id_ = id;
205 }
206
207 index
get_type_id()208 get_type_id() const
209 {
210 return type_id_;
211 }
212
213 private:
214 virtual void set_status_( DictionaryDatum ) = 0;
215
216 virtual DictionaryDatum get_status_() = 0;
217
218
219 /**
220 * Set the number of threads.
221 * @see set_threads()
222 */
223 void set_threads_( thread t );
224
225 /**
226 * Initialize the pool allocator with the Node specific values.
227 */
228 virtual void init_memory_( sli::pool& ) = 0;
229
230 /**
231 * Allocate a new object at the specified memory position.
232 */
233 virtual Node* allocate_( void* ) = 0;
234
235 /**
236 * Name of the Model.
237 * This name will be used to identify all Nodes which are
238 * created by this model object.
239 */
240 std::string name_;
241
242 /**
243 * Identifier of the model C++ type.
244 * For pristine models, the type_id equals the model_id.
245 * For copied models, the type_id equals the type_id of the base model.
246 * This number is needed to automatically save and restore copied models.
247 */
248 index type_id_;
249
250 /**
251 * Memory for all nodes sorted by threads.
252 */
253 std::vector< sli::pool > memory_;
254 };
255
256
257 inline Node*
allocate(thread t)258 Model::allocate( thread t )
259 {
260 assert( ( size_t ) t < memory_.size() );
261 return allocate_( memory_[ t ].alloc() );
262 }
263
264 inline void
free(thread t,Node * n)265 Model::free( thread t, Node* n )
266 {
267 assert( ( size_t ) t < memory_.size() );
268 memory_[ t ].free( n );
269 }
270
271 inline std::string
get_name()272 Model::get_name() const
273 {
274 return name_;
275 }
276 }
277 #endif
278