NEST main@caf0ae8
 
Loading...
Searching...
No Matches
recording_backend_sionlib.h
Go to the documentation of this file.
1/*
2 * recording_backend_sionlib.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 RECORDING_BACKEND_SIONLIB_H
24#define RECORDING_BACKEND_SIONLIB_H
25
26// C includes:
27#include <mpi.h>
28#include <sion.h>
29
30#include "recording_backend.h"
31
32/* BeginUserDocs: NOINDEX
33
34Short description
35+++++++++++++++++
36
37Recording backend `sionlib` - Store data to an efficient binary format
38
39Description
40~~~~~~~~~~~
41
42.. admonition:: Availability
43
44 This recording backend is only available if NEST was compiled with
45 :ref:`support for MPI and SIONlib <compile-with-mpi>`.
46
47The `sionlib` recording backend writes collected data persistently to
48a binary container file (or to a rather small set of such files). This
49is especially useful for large-scale simulations running in a
50distributed way on many MPI processes/OpenMP threads. In such usage
51scenarios, writing to plain text files (see :doc:`recording backend
52for ASCII files </models/recording_backend_ascii>`) would cause a large
53overhead because of the huge number of generated files and thus be
54very inefficient.
55
56The implementation of the `sionlib` backend is based on the `SIONlib
57library <http://www.fz-juelich.de/jsc/sionlib>`_. Depending on the I/O
58architecture of the compute cluster or supercomputer and the global
59settings of the `sionlib` recording backend, either a single container
60file or a set of these files is created. In case of a single file, it
61is named according to the following pattern:
62
63::
64
65 <data_path>/<data_prefix><filename>
66
67In case of multiple files, this name is extended for each file by a
68dot followed by a consecutive number. The properties ``data_path`` and
69``data_prefix`` are global kernel properties. They can for example be
70set during repetitive simulation protocols to separate the data
71originating from individual runs.
72
73The life of a set of associated container files starts with the call
74to ``Prepare`` and ends with the call to ``Cleanup``. Data that is
75produced during successive calls to ``Run`` in between a pair of
76``Prepare`` and ``Cleanup`` calls will be written to the same file
77set. When creating a new recording, if the filename already exists,
78the ``Prepare`` call will fail with a corresponding error message. To
79instead overwrite the old file set, the kernel property
80``overwrite_files`` can be set to ``True`` using the corresponding kernel
81attribute. An alternative way for avoiding name clashes is to set the
82kernel attributes ``data_path`` or ``data_prefix``, to write to a different file.
83
84Data format
85~~~~~~~~~~~
86
87In contrast to other recording backends, the ``sionlib`` backend
88writes the data from all recorders using it to a single container
89file(s). The file(s) contain the data in a custom binary format, which
90is composed of a series of blocks in the following order:
91
92* The *body block* contains the actual data records; the layout of an
93 individual record depends on the type of the device and is described
94 by a corresponding entry in the *device info block*
95
96* The *file info block* keeps the file's metadata, like version
97 information and such
98
99* The *device info block* stores the properties and a data layout
100 description for each device that uses the ``sionlib`` backend
101
102* The *tail block* contains pointers to the *file info block*
103
104The data layout of the NEST SIONlib file format v2 is shown in the
105following figure.
106
107.. figure:: ../static/img/nest_sionlib_file_format_v2.png
108 :alt: NEST SIONlib binary file format
109
110 NEST SIONlib binary file format.
111
112Reading the data
113~~~~~~~~~~~~~~~~
114
115As the binary format of the files produced by the ``sionlib`` does not
116conform to any standard, parsing them manually might be a bit
117cumbersome. To ease this task, we provide a reader module for Python
118that makes the files available in a convenient way. The source code
119and further documentation for this module can be found in its own
120`repository <https://github.com/nest/nest-sionlib-reader>`_.
121
122Recorder-specific parameters
123~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124
125label
126 A recorder-specific string (default: *""*) that serves as alias
127 name for the recording device, and which is stored in the metadata
128 section of the container files.
129
130Global parameters
131~~~~~~~~~~~~~~~~~
132
133These parameters can be set by assigning a nested dictionary to the
134kernel attribute ``recording_backends``. The dictionary has to have
135the form ``{'sionlib': {k_1: v_1, …, k_n: v_n}`` with ``k_i`` being
136from the following list:
137
138filename
139 The filename (default: *"output.sion"*) part of the pattern
140 according to which the full filename (incl. path) is generated (see
141 above).
142
143sion_n_files
144 The number of container files (default: *1*) used for storing the
145 results of a single call to ``Simulate`` (or of a single
146 ``Prepare``-``Run``-``Cleanup`` cycle). The default is one
147 file. Using multiple files may have a performance advantage on
148 large computing clusters, depending on how the (parallel) file
149 system is accessed from the compute nodes.
150
151sion_chunksize
152 In SIONlib nomenclature, a single OpenMP thread running on a single
153 MPI process is called a task. For each task, a specific number of
154 bytes is allocated in the container file(s) from the
155 beginning. This number is set by the parameter ``sion_chunksize``
156 (default: *262144*). If the number of bytes written by each task
157 during the simulation is known in advance, it is advantageous to
158 set the chunk size to this value. In this way, the size of the
159 container files has not to be adjusted by SIONlib during the
160 simulation. This yields a slight performance advantage. Choosing a
161 value for ``sion_chunksize`` which is too large does not hurt that
162 much because SIONlib container files are sparse files (if supported
163 by the underlying file system) which only use up the disk space
164 which is actually required by the stored data.
165
166buffer_size
167 The size of task-specific buffers (default: *1024*) within the
168 `sionlib` recording backend in bytes. These buffers are used to
169 temporarily store data generated by the recording devices on each
170 task. As soon as a buffer is full, its contents are written to the
171 respective container file. To achieve optimum performance, the size
172 of these buffers should at least amount to the size of the file
173 system blocks.
174
175sion_collective
176 Flag (default: *false*) to enable the collective mode of
177 SIONlib. In collective mode, recorded data is buffered completely
178 during ``Run`` and only written at the very end of ``Run`` to the
179 container files, all tasks acting synchronously. Furthermore,
180 within SIONlib so-called collectors aggregate data from a specific
181 number of tasks, and actually only these collectors directly access
182 the container files, in this way minimizing load on the file
183 system. The number of tasks per collector is determined
184 automatically by SIONlib. However, collector size can also be set
185 explicitly by the user via the environment variable SION_COLLSIZE
186 before the start of NEST. On large simulations which also generate
187 a large amount of data, collective mode can offer a performance
188 advantage.
189
190EndUserDocs */
191
192namespace nest
193{
194
196{
197public:
198 const static unsigned int SIONLIB_REC_BACKEND_VERSION;
199 const static unsigned int DEV_NAME_BUFFERSIZE;
200 const static unsigned int DEV_LABEL_BUFFERSIZE;
201 const static unsigned int VALUE_NAME_BUFFERSIZE;
202 const static unsigned int NEST_VERSION_BUFFERSIZE;
203
205
206 ~RecordingBackendSIONlib() throw();
207
208 void initialize() override;
209 void finalize() override;
210
211 void enroll( const RecordingDevice& device, const Dictionary& params ) override;
212
213 void disenroll( const RecordingDevice& device ) override;
214
215 void set_value_names( const RecordingDevice& device,
216 const std::vector< std::string >& double_value_names,
217 const std::vector< std::string >& long_value_names ) override;
218
219 void prepare() override;
220
221 void cleanup() override;
222
223 void write( const RecordingDevice& device,
224 const Event& event,
225 const std::vector< double >& double_values,
226 const std::vector< long >& long_values ) override;
227
228 void set_status( const Dictionary& ) override;
229
230 void get_status( Dictionary& ) const override;
231
232 void pre_run_hook() override;
233
234 void post_run_hook() override;
235
236 void post_step_hook() override;
237
238 void check_device_status( const Dictionary& ) const override;
239 void get_device_defaults( Dictionary& ) const override;
240 void get_device_status( const RecordingDevice& device, Dictionary& params_dictionary ) const override;
241
242private:
243 void open_files_();
244 void close_files_();
245 const std::string build_filename_() const;
246
249
251 {
252 private:
253 char* buffer_;
254 size_t ptr_;
255 size_t max_size_;
256
257 public:
258 SIONBuffer();
259 SIONBuffer( size_t size );
260 ~SIONBuffer();
261
262 void reserve( size_t size );
263 void ensure_space( size_t size );
264 void write( const char* v, size_t n );
265
266 size_t
268 {
269 return max_size_;
270 };
271
272 size_t
274 {
275 return ptr_;
276 };
277
278 size_t
280 {
281 return max_size_ - ptr_;
282 };
283
284 void
286 {
287 ptr_ = 0;
288 };
289
290 char*
292 {
293 return buffer_;
294 };
295
296 template < typename T >
297 SIONBuffer& operator<<( const T data );
298 };
299
301 {
303 : n_rec( 0 )
304 {
305 }
306
307 size_t node_id;
308 unsigned int type;
309 std::string name;
310 std::string label;
311
313
314 unsigned long int n_rec;
315 std::vector< std::string > double_value_names;
316 std::vector< std::string > long_value_names;
317 };
318
320 {
322 : device( device )
323 , info()
324 {
325 }
326
329 };
330
332 {
333 int sid;
335 };
336
337 typedef std::vector< std::map< size_t, DeviceEntry > > device_map;
339
340 typedef std::map< size_t, FileEntry > file_map;
342
343 std::string filename_;
344 MPI_Comm local_comm_; // single copy of local MPI communicator
345 // for all threads using the sionlib
346 // recording backend in parallel (for broadcasting
347 // the results of MPIX..(..) in open_files_(..))
348
349 double t_start_; // simulation start time for storing
350
352 {
353 std::string filename_;
358
359 Parameters_();
360
361 void get( const RecordingBackendSIONlib&, Dictionary& ) const;
362 void set( const RecordingBackendSIONlib&, const Dictionary& );
363 };
364
366};
367
368} // namespace
369
370#endif /* #ifndef RECORDING_BACKEND_SIONLIB_H */
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
Encapsulate information sent between nodes.
Definition event.h:103
Definition recording_backend_sionlib.h:251
size_t get_size()
Definition recording_backend_sionlib.h:273
char * read()
Definition recording_backend_sionlib.h:291
size_t get_free()
Definition recording_backend_sionlib.h:279
SIONBuffer & operator<<(const T data)
size_t get_capacity()
Definition recording_backend_sionlib.h:267
char * buffer_
Definition recording_backend_sionlib.h:253
void clear()
Definition recording_backend_sionlib.h:285
size_t ptr_
Definition recording_backend_sionlib.h:254
size_t max_size_
Definition recording_backend_sionlib.h:255
Definition recording_backend_sionlib.h:196
void get_device_defaults(Dictionary &) const override
Return the per-device defaults by writing it to the given params dictionary.
Definition recording_backend_sionlib.cpp:704
MPI_Comm local_comm_
Definition recording_backend_sionlib.h:344
void set_status(const Dictionary &) override
Set the status of the recording backend using the key-value pairs contained in the params dictionary.
Definition recording_backend_sionlib.cpp:651
std::vector< std::map< size_t, DeviceEntry > > device_map
Definition recording_backend_sionlib.h:337
device_map devices_
Definition recording_backend_sionlib.h:338
const std::string build_filename_() const
Definition recording_backend_sionlib.cpp:515
void disenroll(const RecordingDevice &device) override
Disenroll a RecordingDevice from the RecordingBackend.
Definition recording_backend_sionlib.cpp:101
std::map< size_t, FileEntry > file_map
Definition recording_backend_sionlib.h:340
RecordingBackendSIONlib()
Definition recording_backend_sionlib.cpp:50
void prepare() override
Prepare the backend at begin of the NEST Simulate function.
Definition recording_backend_sionlib.cpp:669
size_t num_enrolled_devices_
Definition recording_backend_sionlib.h:248
~RecordingBackendSIONlib()
Definition recording_backend_sionlib.cpp:56
void get_status(Dictionary &) const override
Return the status of the recording backend by writing it to the given params dictionary.
Definition recording_backend_sionlib.cpp:661
void open_files_()
Definition recording_backend_sionlib.cpp:145
static const unsigned int DEV_NAME_BUFFERSIZE
Definition recording_backend_sionlib.h:199
void cleanup() override
Clean up the backend at the end of a user level call to the NEST Simulate function.
Definition recording_backend_sionlib.cpp:255
void set_value_names(const RecordingDevice &device, const std::vector< std::string > &double_value_names, const std::vector< std::string > &long_value_names) override
To make the names of recorded quantities known to the RecordingBackend, the vectors double_value_name...
Definition recording_backend_sionlib.cpp:114
void close_files_()
Definition recording_backend_sionlib.cpp:261
void finalize() override
Definition recording_backend_sionlib.cpp:69
void post_step_hook() override
Do work required at the end of each simulation step.
Definition recording_backend_sionlib.cpp:680
file_map files_
Definition recording_backend_sionlib.h:341
void write(const RecordingDevice &device, const Event &event, const std::vector< double > &double_values, const std::vector< long > &long_values) override
Write the data from the event to the backend specific channel together with the values given.
Definition recording_backend_sionlib.cpp:421
void pre_run_hook() override
Initialize global backend-specific data structures.
Definition recording_backend_sionlib.cpp:140
double t_start_
Definition recording_backend_sionlib.h:349
std::string filename_
Definition recording_backend_sionlib.h:343
void post_run_hook() override
Clean up the backend at the end of a Run.
Definition recording_backend_sionlib.cpp:675
void get_device_status(const RecordingDevice &device, Dictionary &params_dictionary) const override
Return the per-device status of the given recording device by writing it to the given params dictiona...
Definition recording_backend_sionlib.cpp:710
Parameters_ P_
Definition recording_backend_sionlib.h:365
static const unsigned int DEV_LABEL_BUFFERSIZE
Definition recording_backend_sionlib.h:200
void check_device_status(const Dictionary &) const override
Check if the given per-device properties are valid and usable by the backend.
Definition recording_backend_sionlib.cpp:698
static const unsigned int NEST_VERSION_BUFFERSIZE
Definition recording_backend_sionlib.h:202
void initialize() override
Definition recording_backend_sionlib.cpp:62
static const unsigned int VALUE_NAME_BUFFERSIZE
Definition recording_backend_sionlib.h:201
bool files_opened_
Definition recording_backend_sionlib.h:247
static const unsigned int SIONLIB_REC_BACKEND_VERSION
Definition recording_backend_sionlib.h:198
void enroll(const RecordingDevice &device, const Dictionary &params) override
Enroll a RecordingDevice with the RecordingBackend.
Definition recording_backend_sionlib.cpp:74
Abstract base class for all NESTio recording backends.
Definition recording_backend.h:67
Base class for all recording devices.
Definition recording_device.h:157
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
Definition recording_backend_sionlib.h:320
const RecordingDevice & device
Definition recording_backend_sionlib.h:327
DeviceEntry(const RecordingDevice &device)
Definition recording_backend_sionlib.h:321
DeviceInfo info
Definition recording_backend_sionlib.h:328
Definition recording_backend_sionlib.h:301
std::vector< std::string > double_value_names
Definition recording_backend_sionlib.h:315
unsigned long int n_rec
Definition recording_backend_sionlib.h:314
long t_start
Definition recording_backend_sionlib.h:312
unsigned int type
Definition recording_backend_sionlib.h:308
size_t node_id
Definition recording_backend_sionlib.h:307
std::string name
Definition recording_backend_sionlib.h:309
long origin
Definition recording_backend_sionlib.h:312
DeviceInfo()
Definition recording_backend_sionlib.h:302
std::string label
Definition recording_backend_sionlib.h:310
std::vector< std::string > long_value_names
Definition recording_backend_sionlib.h:316
long t_stop
Definition recording_backend_sionlib.h:312
Definition recording_backend_sionlib.h:332
int sid
Definition recording_backend_sionlib.h:333
SIONBuffer buffer
Definition recording_backend_sionlib.h:334
Definition recording_backend_sionlib.h:352
void set(const RecordingBackendSIONlib &, const Dictionary &)
Definition recording_backend_sionlib.cpp:628
long sion_chunksize_
the size of SIONlib's buffer.
Definition recording_backend_sionlib.h:355
Parameters_()
Definition recording_backend_sionlib.cpp:608
void get(const RecordingBackendSIONlib &, Dictionary &) const
Definition recording_backend_sionlib.cpp:618
bool sion_collective_
use SIONlib's collective mode.
Definition recording_backend_sionlib.h:354
std::string filename_
the file name extension to use, without .
Definition recording_backend_sionlib.h:353
long buffer_size_
the size of the internal buffer.
Definition recording_backend_sionlib.h:357
int sion_n_files_
the number of SIONLIB container files used.
Definition recording_backend_sionlib.h:356