logger.c 30.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*******************************************************************************
 * This file is part of SWIFT.
 * Copyright (c) 2017 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

/* Config parameters. */
#include "../config.h"

23
#ifdef HAVE_POSIX_FALLOCATE /* Are we on a sensible platform? */
lhausamm's avatar
lhausamm committed
24
#ifdef WITH_LOGGER
25

26
/* Some standard headers. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
27
#include <hdf5.h>
28
#include <math.h>
29
#include <stdint.h>
30
31
32
33
34
35
36
37
38
#include <stdlib.h>
#include <string.h>

/* This object's header. */
#include "logger.h"

/* Local headers. */
#include "atomic.h"
#include "dump.h"
Loic Hausammann's avatar
Format    
Loic Hausammann committed
39
#include "engine.h"
40
41
#include "error.h"
#include "part.h"
lhausamm's avatar
lhausamm committed
42
#include "units.h"
43

44
/*
45
46
 * Thoses are definitions from the format and therefore should not be changed!
 */
Loic Hausammann's avatar
Loic Hausammann committed
47
/* Number of bytes for a mask. */
48
// TODO change this to number of bits
Loic Hausammann's avatar
Loic Hausammann committed
49
#define logger_mask_size 2
50

Loic Hausammann's avatar
Loic Hausammann committed
51
/* Number of bits for chunk header. */
52
53
#define logger_header_bytes 8

Loic Hausammann's avatar
Loic Hausammann committed
54
/* Number bytes for an offset. */
55
#define logger_offset_size logger_header_bytes - logger_mask_size
56

Loic Hausammann's avatar
Loic Hausammann committed
57
/* Number of bytes for the file format information. */
Loic Hausammann's avatar
Loic Hausammann committed
58
#define logger_format_size 20
59

Loic Hausammann's avatar
Loic Hausammann committed
60
/* Number of bytes for the labels in the header. */
61
#define logger_label_size 20
62

Loic Hausammann's avatar
Loic Hausammann committed
63
char logger_file_format[logger_format_size] = "SWIFT_LOGGER";
lhausamm's avatar
lhausamm committed
64

Loic Hausammann's avatar
Loic Hausammann committed
65
const struct mask_data logger_mask_data[logger_count_mask] = {
Loic Hausammann's avatar
Loic Hausammann committed
66
    /* Particle's position. */
Loic Hausammann's avatar
Loic Hausammann committed
67
    {3 * sizeof(double), 1 << logger_x, "positions"},
Loic Hausammann's avatar
Loic Hausammann committed
68
    /* Particle's velocity. */
Loic Hausammann's avatar
Loic Hausammann committed
69
    {3 * sizeof(float), 1 << logger_v, "velocities"},
Loic Hausammann's avatar
Loic Hausammann committed
70
    /* Particle's acceleration. */
Loic Hausammann's avatar
Loic Hausammann committed
71
    {3 * sizeof(float), 1 << logger_a, "accelerations"},
Loic Hausammann's avatar
Loic Hausammann committed
72
    /* Particle's entropy. */
Loic Hausammann's avatar
Loic Hausammann committed
73
    {sizeof(float), 1 << logger_u, "entropy"},
Loic Hausammann's avatar
Loic Hausammann committed
74
    /* Particle's smoothing length. */
Loic Hausammann's avatar
Loic Hausammann committed
75
    {sizeof(float), 1 << logger_h, "smoothing length"},
Loic Hausammann's avatar
Loic Hausammann committed
76
    /* Particle's density. */
Loic Hausammann's avatar
Loic Hausammann committed
77
    {sizeof(float), 1 << logger_rho, "density"},
Loic Hausammann's avatar
Loic Hausammann committed
78
    /* Particle's constants: mass (float) and ID (long long). */
Loic Hausammann's avatar
Loic Hausammann committed
79
    {sizeof(float) + sizeof(long long), 1 << logger_consts, "consts"},
Loic Hausammann's avatar
Loic Hausammann committed
80
81
    /* Flag for special cases (e.g. change of MPI rank, star formation, ...) */
    {sizeof(int), 1 << logger_special_flags, "special flags"},
Loic Hausammann's avatar
Loic Hausammann committed
82
    /* Simulation time stamp: integertime and double time (e.g. scale
Loic Hausammann's avatar
Loic Hausammann committed
83
       factor or time). */
Loic Hausammann's avatar
Loic Hausammann committed
84
    {sizeof(integertime_t) + sizeof(double), 1 << logger_timestamp,
Loic Hausammann's avatar
Loic Hausammann committed
85
86
     "timestamp"},
};
87

lhausamm's avatar
lhausamm committed
88
/**
89
90
91
 * @brief Write the header of a chunk (offset + mask).
 *
 * This is maybe broken for big(?) endian.
lhausamm's avatar
lhausamm committed
92
93
94
95
96
97
98
99
 *
 * @param buff The writing buffer
 * @param mask The mask to write
 * @param offset The old offset
 * @param offset_new The new offset
 *
 * @return updated buff
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
100
101
char *logger_write_chunk_header(char *buff, const unsigned int *mask,
                                const size_t *offset, const size_t offset_new) {
Loic Hausammann's avatar
Loic Hausammann committed
102
  /* write mask. */
103
104
  memcpy(buff, mask, logger_mask_size);
  buff += logger_mask_size;
lhausamm's avatar
lhausamm committed
105

Loic Hausammann's avatar
Loic Hausammann committed
106
  /* write offset. */
Loic Hausammann's avatar
Loic Hausammann committed
107
  uint64_t diff_offset = offset_new - *offset;
108
109
  memcpy(buff, &diff_offset, logger_offset_size);
  buff += logger_offset_size;
lhausamm's avatar
lhausamm committed
110
111
112
113
114

  return buff;
}

/**
Loic Hausammann's avatar
Loic Hausammann committed
115
 * @brief Write to the dump.
lhausamm's avatar
lhausamm committed
116
117
 *
 * @param d #dump file
lhausamm's avatar
lhausamm committed
118
 * @param offset (return) offset of the data
lhausamm's avatar
lhausamm committed
119
120
121
 * @param size number of bytes to write
 * @param p pointer to the data
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
122
123
void logger_write_data(struct dump *d, size_t *offset, size_t size,
                       const void *p) {
Loic Hausammann's avatar
Loic Hausammann committed
124
  /* get buffer. */
lhausamm's avatar
lhausamm committed
125
  char *buff = dump_get(d, size, offset);
lhausamm's avatar
lhausamm committed
126

Loic Hausammann's avatar
Loic Hausammann committed
127
  /* write data to the buffer. */
128
  memcpy(buff, p, size);
129

Loic Hausammann's avatar
Loic Hausammann committed
130
  /* Update offset to end of chunk. */
131
  *offset += size;
132
133
}

134
135
/**
 * @brief Compute the size of a message given its mask.
136
137
138
139
 *
 * @param mask The mask that will be used to dump a #part or #gpart.
 *
 * @return The size of the logger message in bytes.
140
 */
lhausamm's avatar
lhausamm committed
141
int logger_compute_chunk_size(unsigned int mask) {
142
143

  /* Start with 8 bytes for the header. */
lhausamm's avatar
lhausamm committed
144
  int size = logger_mask_size + logger_offset_size;
145
146

  /* Is this a particle or a timestep? */
147
  if (mask & logger_mask_data[logger_timestamp].mask) {
148
149

    /* The timestamp should not contain any other bits. */
150
    if (mask != logger_mask_data[logger_timestamp].mask)
151
152
153
      error("Timestamps should not include any other data.");

    /* A timestamp consists of an unsigned long long int. */
154
    size += logger_mask_data[logger_timestamp].size;
155
156
157

  } else {

Loic Hausammann's avatar
Loic Hausammann committed
158
    for (int i = 0; i < logger_count_mask; i++) {
159
      if (mask & logger_mask_data[i].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
160
        size += logger_mask_data[i].size;
161
      }
Loic Hausammann's avatar
Loic Hausammann committed
162
    }
163
164
165
166
  }

  return size;
}
167

lhausamm's avatar
lhausamm committed
168
/**
lhausamm's avatar
lhausamm committed
169
 * @brief log all particles in the engine.
lhausamm's avatar
lhausamm committed
170
 *
Loic Hausammann's avatar
Loic Hausammann committed
171
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
172
 * @param e The #engine
lhausamm's avatar
lhausamm committed
173
 */
Loic Hausammann's avatar
Loic Hausammann committed
174
void logger_log_all(struct logger_writer *log, const struct engine *e) {
175

Loic Hausammann's avatar
Loic Hausammann committed
176
  /* Ensure that enough space is available. */
Loic Hausammann's avatar
Loic Hausammann committed
177
  logger_ensure_size(log, e->s->nr_parts, e->s->nr_gparts, e->s->nr_sparts);
178

Loic Hausammann's avatar
Loic Hausammann committed
179
  /* some constants. */
lhausamm's avatar
lhausamm committed
180
  const struct space *s = e->s;
lhausamm's avatar
lhausamm committed
181

Loic Hausammann's avatar
Loic Hausammann committed
182
  /* loop over all parts. */
Loic Hausammann's avatar
Loic Hausammann committed
183
  for (size_t i = 0; i < s->nr_parts; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
184
    logger_log_part(log, &s->parts[i], logger_masks_all_part,
Loic Hausammann's avatar
Loic Hausammann committed
185
186
                    &s->xparts[i].logger_data.last_offset,
                    /* Special flags */ 0);
187
    s->xparts[i].logger_data.steps_since_last_output = 0;
lhausamm's avatar
lhausamm committed
188
  }
lhausamm's avatar
lhausamm committed
189

Loic Hausammann's avatar
Loic Hausammann committed
190
191
192
193
194
  /* loop over all gparts */
  for (size_t i = 0; i < s->nr_gparts; i++) {
    /* Log only the dark matter */
    if (s->gparts[i].type != swift_type_dark_matter) continue;

Loic Hausammann's avatar
Loic Hausammann committed
195
    logger_log_gpart(log, &s->gparts[i], logger_masks_all_gpart,
Loic Hausammann's avatar
Loic Hausammann committed
196
197
198
199
200
201
202
                     &s->gparts[i].logger_data.last_offset,
                     /* Special flags */ 0);
    s->gparts[i].logger_data.steps_since_last_output = 0;
  }

  /* loop over all sparts */
  for (size_t i = 0; i < s->nr_sparts; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
203
    logger_log_spart(log, &s->sparts[i], logger_masks_all_spart,
Loic Hausammann's avatar
Loic Hausammann committed
204
205
206
207
                     &s->sparts[i].logger_data.last_offset,
                     /* Special flags */ 0);
    s->sparts[i].logger_data.steps_since_last_output = 0;
  }
lhausamm's avatar
lhausamm committed
208

Loic Hausammann's avatar
Loic Hausammann committed
209
  if (e->total_nr_bparts > 0) error("Not implemented");
lhausamm's avatar
lhausamm committed
210
211
}

212
213
214
/**
 * @brief Dump a #part to the log.
 *
Loic Hausammann's avatar
Loic Hausammann committed
215
 * @param log The #logger_writer
Pedro Gonnet's avatar
Pedro Gonnet committed
216
 * @param p The #part to dump.
217
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
218
219
 * @param offset Pointer to the offset of the previous log of this particle;
 * (return) offset of this log.
Loic Hausammann's avatar
Loic Hausammann committed
220
 * @param special_flags The value of the special flag.
221
 */
Loic Hausammann's avatar
Loic Hausammann committed
222
void logger_log_part(struct logger_writer *log, const struct part *p,
Loic Hausammann's avatar
Loic Hausammann committed
223
224
                     unsigned int mask, size_t *offset,
                     const int special_flags) {
225
226

  /* Make sure we're not writing a timestamp. */
227
  if (mask & logger_mask_data[logger_timestamp].mask)
228
229
230
    error("You should not log particles as timestamps.");

  /* Start by computing the size of the message. */
lhausamm's avatar
lhausamm committed
231
  const int size = logger_compute_chunk_size(mask);
232
233
234

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
235
  char *buff = (char *)dump_get(&log->dump, size, &offset_new);
236
237

  /* Write the header. */
lhausamm's avatar
lhausamm committed
238
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
239
240

  /* Particle position as three doubles. */
241
  if (mask & logger_mask_data[logger_x].mask) {
242
243
    memcpy(buff, p->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
244
245
246
  }

  /* Particle velocity as three floats. */
247
  if (mask & logger_mask_data[logger_v].mask) {
248
249
    memcpy(buff, p->v, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
250
251
252
  }

  /* Particle accelleration as three floats. */
253
  if (mask & logger_mask_data[logger_a].mask) {
254
255
    memcpy(buff, p->a_hydro, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
256
257
  }

258
259
#if defined(GADGET2_SPH)

260
  /* Particle internal energy as a single float. */
261
  if (mask & logger_mask_data[logger_u].mask) {
262
263
    memcpy(buff, &p->entropy, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
264
265
266
  }

  /* Particle smoothing length as a single float. */
267
  if (mask & logger_mask_data[logger_h].mask) {
268
269
    memcpy(buff, &p->h, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
270
271
272
  }

  /* Particle density as a single float. */
273
  if (mask & logger_mask_data[logger_rho].mask) {
274
275
    memcpy(buff, &p->rho, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
276
277
278
  }

  /* Particle constants, which is a bit more complicated. */
279
  if (mask & logger_mask_data[logger_consts].mask) {
280
    // TODO make it dependent of logger_mask_data
281
282
    memcpy(buff, &p->mass, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
283
284
285
    const int64_t id = p->id;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
286
287
  }

288
289
#endif

Loic Hausammann's avatar
Loic Hausammann committed
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  /* Special flags */
  if (mask & logger_mask_data[logger_special_flags].mask) {
    memcpy(buff, &special_flags, logger_mask_data[logger_special_flags].size);
    buff += logger_mask_data[logger_special_flags].size;
  }

  /* Update the log message offset. */
  *offset = offset_new;
}

/**
 * @brief Dump a #spart to the log.
 *
 * @param log The #logger_writer
 * @param sp The #spart to dump.
 * @param mask The mask of the data to dump.
 * @param offset Pointer to the offset of the previous log of this particle;
 * @param special_flags The value of the special flag.
 * (return) offset of this log.
 */
void logger_log_spart(struct logger_writer *log, const struct spart *sp,
                      unsigned int mask, size_t *offset,
                      const int special_flags) {

  /* Make sure we're not writing a timestamp. */
  if (mask & logger_mask_data[logger_timestamp].mask)
    error("You should not log particles as timestamps.");

  /* Make sure we're not looging fields not supported by gparts. */
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask |
       logger_mask_data[logger_a].mask))
    error("Can't log SPH quantities for sparts.");

  /* Start by computing the size of the message. */
  const int size = logger_compute_chunk_size(mask);

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
  char *buff = (char *)dump_get(&log->dump, size, &offset_new);

  /* Write the header. */
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);

  /* Particle position as three doubles. */
  if (mask & logger_mask_data[logger_x].mask) {
    memcpy(buff, sp->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
  }

  /* Particle velocity as three floats. */
  if (mask & logger_mask_data[logger_v].mask) {
    memcpy(buff, sp->v, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
  }

  /* Particle constants, which is a bit more complicated. */
  if (mask & logger_mask_data[logger_consts].mask) {
    // TODO make it dependent of logger_mask_data
    memcpy(buff, &sp->mass, sizeof(float));
    buff += sizeof(float);
    const int64_t id = sp->id;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
  }

  /* Special flags */
  if (mask & logger_mask_data[logger_special_flags].mask) {
    memcpy(buff, &special_flags, logger_mask_data[logger_special_flags].size);
    buff += logger_mask_data[logger_special_flags].size;
  }

362
363
364
  /* Update the log message offset. */
  *offset = offset_new;
}
365
366
367
368

/**
 * @brief Dump a #gpart to the log.
 *
Loic Hausammann's avatar
Loic Hausammann committed
369
 * @param log The #logger_writer
Pedro Gonnet's avatar
Pedro Gonnet committed
370
 * @param p The #gpart to dump.
371
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
372
 * @param offset Pointer to the offset of the previous log of this particle;
Loic Hausammann's avatar
Loic Hausammann committed
373
 * @param special_flags The value of the special flags.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
374
 * (return) offset of this log.
375
 */
Loic Hausammann's avatar
Loic Hausammann committed
376
void logger_log_gpart(struct logger_writer *log, const struct gpart *p,
Loic Hausammann's avatar
Loic Hausammann committed
377
378
379
380
381
382
383
384
                      unsigned int mask, size_t *offset,
                      const int special_flags) {

#ifdef SWIFT_DEBUG_CHECKS
  if (p->id_or_neg_offset < 0) {
    error("Cannot log a gpart attached to another particle");
  }
#endif
385
386

  /* Make sure we're not writing a timestamp. */
387
  if (mask & logger_mask_data[logger_timestamp].mask)
388
389
390
    error("You should not log particles as timestamps.");

  /* Make sure we're not looging fields not supported by gparts. */
391
392
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask))
393
394
395
    error("Can't log SPH quantities for gparts.");

  /* Start by computing the size of the message. */
lhausamm's avatar
lhausamm committed
396
  const int size = logger_compute_chunk_size(mask);
397
398
399

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
400
  char *buff = (char *)dump_get(&log->dump, size, &offset_new);
401
402

  /* Write the header. */
lhausamm's avatar
lhausamm committed
403
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
404
405

  /* Particle position as three doubles. */
406
  if (mask & logger_mask_data[logger_x].mask) {
407
408
    memcpy(buff, p->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
409
410
411
  }

  /* Particle velocity as three floats. */
412
  if (mask & logger_mask_data[logger_v].mask) {
413
414
    memcpy(buff, p->v_full, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
415
416
417
  }

  /* Particle accelleration as three floats. */
418
  if (mask & logger_mask_data[logger_a].mask) {
419
420
    memcpy(buff, p->a_grav, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
421
422
423
  }

  /* Particle constants, which is a bit more complicated. */
424
  if (mask & logger_mask_data[logger_consts].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
425
    // TODO make it dependent of logger_mask_data.
426
427
    memcpy(buff, &p->mass, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
428
429
430
431
432
433
434
435
436
    const int64_t id = p->id_or_neg_offset;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
  }

  /* Special flags */
  if (mask & logger_mask_data[logger_special_flags].mask) {
    memcpy(buff, &special_flags, logger_mask_data[logger_special_flags].size);
    buff += logger_mask_data[logger_special_flags].size;
437
438
439
440
441
442
  }

  /* Update the log message offset. */
  *offset = offset_new;
}

lhausamm's avatar
lhausamm committed
443
444
445
/**
 * @brief write a timestamp
 *
Loic Hausammann's avatar
Loic Hausammann committed
446
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
447
 * @param timestamp time to write
448
 * @param time time or scale factor
Loic Hausammann's avatar
Format    
Loic Hausammann committed
449
450
 * @param offset Pointer to the offset of the previous log of this particle;
 * (return) offset of this log.
lhausamm's avatar
lhausamm committed
451
 */
Loic Hausammann's avatar
Loic Hausammann committed
452
void logger_log_timestamp(struct logger_writer *log, integertime_t timestamp,
453
                          double time, size_t *offset) {
454
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
455

456
  /* Start by computing the size of the message. */
457
458
  const int size =
      logger_compute_chunk_size(logger_mask_data[logger_timestamp].mask);
459
460
461

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
462
  char *buff = (char *)dump_get(dump, size, &offset_new);
463
464

  /* Write the header. */
465
  unsigned int mask = logger_mask_data[logger_timestamp].mask;
lhausamm's avatar
lhausamm committed
466
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
Pedro Gonnet's avatar
Pedro Gonnet committed
467

468
  /* Store the timestamp. */
Loic Hausammann's avatar
Loic Hausammann committed
469
  // TODO make it dependent of logger_mask_data.
470
  memcpy(buff, &timestamp, sizeof(integertime_t));
471
472
  buff += sizeof(integertime_t);

Loic Hausammann's avatar
Loic Hausammann committed
473
  /* Store the time. */
474
  memcpy(buff, &time, sizeof(double));
475
476
477
478

  /* Update the log message offset. */
  *offset = offset_new;
}
Pedro Gonnet's avatar
Pedro Gonnet committed
479

lhausamm's avatar
lhausamm committed
480
/**
lhausamm's avatar
lhausamm committed
481
 * @brief Ensure that the buffer is large enough for a step.
lhausamm's avatar
lhausamm committed
482
483
 *
 * Check if logger parameters are large enough to write all particles
lhausamm's avatar
lhausamm committed
484
 * and ensure that enough space is available in the buffer.
lhausamm's avatar
lhausamm committed
485
 *
Loic Hausammann's avatar
Loic Hausammann committed
486
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
487
488
489
 * @param total_nr_parts total number of part
 * @param total_nr_gparts total number of gpart
 * @param total_nr_sparts total number of spart
lhausamm's avatar
lhausamm committed
490
 */
Loic Hausammann's avatar
Loic Hausammann committed
491
void logger_ensure_size(struct logger_writer *log, size_t total_nr_parts,
Loic Hausammann's avatar
Format    
Loic Hausammann committed
492
                        size_t total_nr_gparts, size_t total_nr_sparts) {
lhausamm's avatar
lhausamm committed
493

Loic Hausammann's avatar
Loic Hausammann committed
494
495
  /* count part memory */
  size_t limit = 0;
lhausamm's avatar
lhausamm committed
496

Loic Hausammann's avatar
Loic Hausammann committed
497
498
  /* count part memory */
  limit += total_nr_parts;
lhausamm's avatar
lhausamm committed
499

Loic Hausammann's avatar
Loic Hausammann committed
500
501
  /* count gpart memory */
  limit += total_nr_gparts;
502

Loic Hausammann's avatar
Loic Hausammann committed
503
  /* count spart memory. */
Loic Hausammann's avatar
Loic Hausammann committed
504
  limit += total_nr_sparts;
lhausamm's avatar
lhausamm committed
505

Loic Hausammann's avatar
Loic Hausammann committed
506
507
508
509
  // TODO improve estimate with the size of each particle
  limit *= log->max_chunk_size;

  /* ensure enough space in dump */
510
  dump_ensure(&log->dump, limit, log->buffer_scale * limit);
lhausamm's avatar
lhausamm committed
511
512
}

513
514
515
516
517
518
519
520
521
/** @brief Generate the name of the dump files
 *
 * @param log The #logger_writer.
 * @param filename The filename of the dump file.
 */
void logger_get_dump_name(struct logger_writer *log, char *filename) {
  sprintf(filename, "%s_%04i.dump", log->base_name, engine_rank);
}

lhausamm's avatar
lhausamm committed
522
523
524
/**
 * @brief intialize the logger structure
 *
Loic Hausammann's avatar
Loic Hausammann committed
525
 * @param log The #logger_writer
526
 * @param params The #swift_params
lhausamm's avatar
lhausamm committed
527
 */
Loic Hausammann's avatar
Loic Hausammann committed
528
529
void logger_init(struct logger_writer *log, struct swift_params *params) {
  /* read parameters. */
lhausamm's avatar
lhausamm committed
530
  log->delta_step = parser_get_param_int(params, "Logger:delta_step");
Loic Hausammann's avatar
Loic Hausammann committed
531
  size_t buffer_size =
Loic Hausammann's avatar
Loic Hausammann committed
532
533
      parser_get_opt_param_float(params, "Logger:initial_buffer_size", 0.5) *
      1e9;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
534
  log->buffer_scale =
535
      parser_get_opt_param_float(params, "Logger:buffer_scale", 10);
lhausamm's avatar
lhausamm committed
536
537
  parser_get_param_string(params, "Logger:basename", log->base_name);

Loic Hausammann's avatar
Loic Hausammann committed
538
539
540
  log->index.mem_frac =
      parser_get_opt_param_float(params, "Logger:index_mem_frac", 0.05);

Loic Hausammann's avatar
Loic Hausammann committed
541
  /* set initial value of parameters. */
lhausamm's avatar
lhausamm committed
542
  log->timestamp_offset = 0;
Loic Hausammann's avatar
Loic Hausammann committed
543
  log->index.dump_size_last_output = 0;
lhausamm's avatar
lhausamm committed
544

Loic Hausammann's avatar
Loic Hausammann committed
545
  /* generate dump filename. */
lhausamm's avatar
lhausamm committed
546
  char logger_name_file[PARSER_MAX_LINE_SIZE];
547
  logger_get_dump_name(log, logger_name_file);
lhausamm's avatar
lhausamm committed
548

Loic Hausammann's avatar
Loic Hausammann committed
549
  /* Compute max size for a particle chunk. */
550
551
  int max_size = logger_offset_size + logger_mask_size;

Loic Hausammann's avatar
Loic Hausammann committed
552
  /* Loop over all fields except timestamp. */
553
554
555
556
  for (int i = 0; i < logger_count_mask - 1; i++) {
    max_size += logger_mask_data[i].size;
  }
  log->max_chunk_size = max_size;
557

Loic Hausammann's avatar
Loic Hausammann committed
558
  /* init dump. */
559
  dump_init(&log->dump, logger_name_file, buffer_size);
lhausamm's avatar
lhausamm committed
560
561
562
563
564
}

/**
 * @brief Close dump file and desallocate memory
 *
Loic Hausammann's avatar
Loic Hausammann committed
565
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
566
 */
Loic Hausammann's avatar
Loic Hausammann committed
567
void logger_free(struct logger_writer *log) { dump_close(&log->dump); }
lhausamm's avatar
lhausamm committed
568

569
570
571
/**
 * @brief Write a file header to a logger file
 *
Loic Hausammann's avatar
Loic Hausammann committed
572
 * @param log The #logger_writer
573
574
 *
 */
Loic Hausammann's avatar
Loic Hausammann committed
575
void logger_write_file_header(struct logger_writer *log) {
lhausamm's avatar
lhausamm committed
576

Loic Hausammann's avatar
Loic Hausammann committed
577
  /* get required variables. */
578
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
579

Loic Hausammann's avatar
Loic Hausammann committed
580
  uint64_t file_offset = dump->file_offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
581

lhausamm's avatar
lhausamm committed
582
  if (file_offset != 0)
Loic Hausammann's avatar
Format    
Loic Hausammann committed
583
584
585
    error(
        "The logger is not empty."
        "This function should be called before writing anything in the logger");
586

Loic Hausammann's avatar
Loic Hausammann committed
587
  /* Write format information. */
Loic Hausammann's avatar
Loic Hausammann committed
588
589
  logger_write_data(dump, &file_offset, logger_format_size,
                    &logger_file_format);
Loic Hausammann's avatar
Loic Hausammann committed
590

Loic Hausammann's avatar
Loic Hausammann committed
591
  /* Write the major version number. */
Loic Hausammann's avatar
Loic Hausammann committed
592
593
594
  int major = logger_major_version;
  logger_write_data(dump, &file_offset, sizeof(int), &major);

Loic Hausammann's avatar
Loic Hausammann committed
595
  /* Write the minor version number. */
Loic Hausammann's avatar
Loic Hausammann committed
596
597
  int minor = logger_minor_version;
  logger_write_data(dump, &file_offset, sizeof(int), &minor);
Loic Hausammann's avatar
Format    
Loic Hausammann committed
598

Loic Hausammann's avatar
Loic Hausammann committed
599
  /* write offset direction. */
600
  const int reversed = 0;
601
  logger_write_data(dump, &file_offset, sizeof(int), &reversed);
lhausamm's avatar
lhausamm committed
602

Loic Hausammann's avatar
Loic Hausammann committed
603
  /* placeholder to write the offset of the first log here. */
604
  char *skip_header = dump_get(dump, logger_offset_size, &file_offset);
605

Loic Hausammann's avatar
Loic Hausammann committed
606
  /* write number of bytes used for names. */
607
608
  const unsigned int label_size = logger_label_size;
  logger_write_data(dump, &file_offset, sizeof(unsigned int), &label_size);
lhausamm's avatar
lhausamm committed
609

Loic Hausammann's avatar
Loic Hausammann committed
610
  /* write number of masks. */
611
612
  const unsigned int count_mask = logger_count_mask;
  logger_write_data(dump, &file_offset, sizeof(unsigned int), &count_mask);
613

Loic Hausammann's avatar
Loic Hausammann committed
614
615
  /* write masks. */
  // loop over all mask type.
616
  for (int i = 0; i < logger_count_mask; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
617
    // mask name.
618
    logger_write_data(dump, &file_offset, logger_label_size,
619
                      &logger_mask_data[i].name);
620

Loic Hausammann's avatar
Loic Hausammann committed
621
    // mask size.
622
    logger_write_data(dump, &file_offset, sizeof(unsigned int),
623
                      &logger_mask_data[i].size);
624
  }
625

Loic Hausammann's avatar
Loic Hausammann committed
626
  /* last step: write first offset. */
627
  memcpy(skip_header, &file_offset, logger_offset_size);
lhausamm's avatar
lhausamm committed
628
}
629

lhausamm's avatar
lhausamm committed
630
631
632
633
634
/**
 * @brief read chunk header
 *
 * @param buff The reading buffer
 * @param mask The mask to read
lhausamm's avatar
lhausamm committed
635
 * @param offset (return) the offset pointed by this chunk (absolute)
Loic Hausammann's avatar
Loic Hausammann committed
636
 * @param cur_offset The current chunk offset
lhausamm's avatar
lhausamm committed
637
638
639
 *
 * @return Number of bytes read
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
640
641
__attribute__((always_inline)) INLINE static int logger_read_chunk_header(
    const char *buff, unsigned int *mask, size_t *offset, size_t cur_offset) {
lhausamm's avatar
lhausamm committed
642
643
  memcpy(mask, buff, logger_mask_size);
  buff += logger_mask_size;
lhausamm's avatar
lhausamm committed
644
645

  *offset = 0;
lhausamm's avatar
lhausamm committed
646
  memcpy(offset, buff, logger_offset_size);
lhausamm's avatar
lhausamm committed
647
  *offset = cur_offset - *offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
648

lhausamm's avatar
lhausamm committed
649
  return logger_mask_size + logger_offset_size;
lhausamm's avatar
lhausamm committed
650
651
}

Pedro Gonnet's avatar
Pedro Gonnet committed
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
/**
 * @brief Read a logger message and store the data in a #part.
 *
 * @param p The #part in which to store the values.
 * @param offset Pointer to the offset of the logger message in the buffer,
 *        will be overwritten with the offset of the previous message.
 * @param buff Pointer to the start of an encoded logger message.
 *
 * @return The mask containing the values read.
 */
int logger_read_part(struct part *p, size_t *offset, const char *buff) {

  /* Jump to the offset. */
  buff = &buff[*offset];

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
668
669
670
  const size_t cur_offset = *offset;
  unsigned int mask = 0;
  buff += logger_read_chunk_header(buff, &mask, offset, cur_offset);
Pedro Gonnet's avatar
Pedro Gonnet committed
671
672

  /* We are only interested in particle data. */
673
  if (mask & logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
674
675
676
    error("Trying to read timestamp as particle.");

  /* Particle position as three doubles. */
677
  if (mask & logger_mask_data[logger_x].mask) {
678
679
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
680
681
682
  }

  /* Particle velocity as three floats. */
683
  if (mask & logger_mask_data[logger_v].mask) {
684
685
    memcpy(p->v, buff, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
686
687
688
  }

  /* Particle accelleration as three floats. */
689
  if (mask & logger_mask_data[logger_a].mask) {
690
691
    memcpy(p->a_hydro, buff, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
692
693
  }

694
695
#if defined(GADGET2_SPH)

Pedro Gonnet's avatar
Pedro Gonnet committed
696
  /* Particle internal energy as a single float. */
697
  if (mask & logger_mask_data[logger_u].mask) {
698
699
    memcpy(&p->entropy, buff, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
700
701
702
  }

  /* Particle smoothing length as a single float. */
703
  if (mask & logger_mask_data[logger_h].mask) {
704
705
    memcpy(&p->h, buff, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
706
707
708
  }

  /* Particle density as a single float. */
709
  if (mask & logger_mask_data[logger_rho].mask) {
710
711
    memcpy(&p->rho, buff, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
712
713
714
  }

  /* Particle constants, which is a bit more complicated. */
715
  if (mask & logger_mask_data[logger_rho].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
716
    // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
717
718
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
719
720
721
722
    int64_t id = 0;
    memcpy(&id, buff, sizeof(int64_t));
    p->id = id;
    buff += sizeof(int64_t);
Pedro Gonnet's avatar
Pedro Gonnet committed
723
724
  }

725
726
#endif

Pedro Gonnet's avatar
Pedro Gonnet committed
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
  /* Finally, return the mask of the values we just read. */
  return mask;
}

/**
 * @brief Read a logger message and store the data in a #gpart.
 *
 * @param p The #gpart in which to store the values.
 * @param offset Pointer to the offset of the logger message in the buffer,
 *        will be overwritten with the offset of the previous message.
 * @param buff Pointer to the start of an encoded logger message.
 *
 * @return The mask containing the values read.
 */
int logger_read_gpart(struct gpart *p, size_t *offset, const char *buff) {

  /* Jump to the offset. */
  buff = &buff[*offset];

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
747
748
749
  const size_t cur_offset = *offset;
  unsigned int mask = 0;
  buff += logger_read_chunk_header(buff, &mask, offset, cur_offset);
Pedro Gonnet's avatar
Pedro Gonnet committed
750
751

  /* We are only interested in particle data. */
752
  if (mask & logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
753
    error("Trying to read timestamp as particle.");
Pedro Gonnet's avatar
Pedro Gonnet committed
754

Pedro Gonnet's avatar
Pedro Gonnet committed
755
  /* We can't store all part fields in a gpart. */
756
757
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask))
Pedro Gonnet's avatar
Pedro Gonnet committed
758
759
760
    error("Trying to read SPH quantities into a gpart.");

  /* Particle position as three doubles. */
761
  if (mask & logger_mask_data[logger_x].mask) {
762
763
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
764
765
766
  }

  /* Particle velocity as three floats. */
767
  if (mask & logger_mask_data[logger_v].mask) {
768
769
    memcpy(p->v_full, buff, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
770
771
772
  }

  /* Particle accelleration as three floats. */
773
  if (mask & logger_mask_data[logger_a].mask) {
774
775
    memcpy(p->a_grav, buff, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
776
777
778
  }

  /* Particle constants, which is a bit more complicated. */
779
  if (mask & logger_mask_data[logger_rho].mask) {
780
    // TODO make it dependent of logger_mask_data
Pedro Gonnet's avatar
Pedro Gonnet committed
781
782
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
783
784
785
    int64_t id = p->id_or_neg_offset;
    memcpy(&id, buff, sizeof(int64_t));
    buff += sizeof(int64_t);
Pedro Gonnet's avatar
Pedro Gonnet committed
786
787
788
789
790
791
792
793
794
795
  }

  /* Finally, return the mask of the values we just read. */
  return mask;
}

/**
 * @brief Read a logger message for a timestamp.
 *
 * @param t The timestamp in which to store the value.
Loic Hausammann's avatar
Loic Hausammann committed
796
 * @param time The time in which to store the value.
Pedro Gonnet's avatar
Pedro Gonnet committed
797
798
799
800
801
802
 * @param offset Pointer to the offset of the logger message in the buffer,
 *        will be overwritten with the offset of the previous message.
 * @param buff Pointer to the start of an encoded logger message.
 *
 * @return The mask containing the values read.
 */
803
804
int logger_read_timestamp(unsigned long long int *t, double *time,
                          size_t *offset, const char *buff) {
Pedro Gonnet's avatar
Pedro Gonnet committed
805
806
807
808
809

  /* Jump to the offset. */
  buff = &buff[*offset];

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
810
811
812
  const size_t cur_offset = *offset;
  unsigned int mask = 0;
  buff += logger_read_chunk_header(buff, &mask, offset, cur_offset);
Pedro Gonnet's avatar
Pedro Gonnet committed
813
814

  /* We are only interested in timestamps. */
815
  if (!(mask & logger_mask_data[logger_timestamp].mask))
Pedro Gonnet's avatar
Pedro Gonnet committed
816
    error("Trying to read timestamp from a particle.");
Pedro Gonnet's avatar
Pedro Gonnet committed
817

Pedro Gonnet's avatar
Pedro Gonnet committed
818
  /* Make sure we don't have extra fields. */
819
  if (mask != logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
820
821
822
    error("Timestamp message contains extra fields.");

  /* Copy the timestamp value from the buffer. */
Loic Hausammann's avatar
Loic Hausammann committed
823
  // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
824
  memcpy(t, buff, sizeof(unsigned long long int));
825
826
827
  buff += sizeof(unsigned long long int);

  /* Copy the timestamp value from the buffer. */
828
  memcpy(time, buff, sizeof(double));
Pedro Gonnet's avatar
Pedro Gonnet committed
829
830
831
832

  /* Finally, return the mask of the values we just read. */
  return mask;
}
833

834
835
836
837
838

#ifdef WITH_MPI
/**
 * @brief Log all the particles leaving the current rank.
 *
839
840
841
 * @param log The #logger_writer.
 * @param nr_nodes Number of nodes used in the simulation.
 * @param sneding Are we sending the particles (or receiving)?
842
843
844
845
846
847
848
849
850
851
852
853
854
855
 * @param parts The list of #part.
 * @param nr_parts The number of parts.
 * @param count The number of parts in each ranks.
 * @param gparts The list of #gpart.
 * @param nr_gparts The number of gparts.
 * @param gcount The number of gparts in each ranks.
 * @param sparts The list of #spart.
 * @param nr_sparts The number of sparts.
 * @param s_counts The number of sparts in each ranks.
 * @param bparts The list of #bpart.
 * @param nr_bparts The number of bparts.
 * @param b_counts The number of bparts in each ranks.
 *
 */
856
857
858
void logger_log_repartition(
    struct logger_writer *log, int nr_nodes, int sending, struct part *parts,
    struct xpart *xparts, size_t nr_parts, int *counts,
859
860
861
862
    struct gpart *gparts, size_t nr_gparts, int *g_counts,
    struct spart *sparts, size_t nr_sparts, int *s_counts,
    struct bpart *bparts, size_t nr_bparts, int *b_counts) {

863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
  size_t part_offset = 0;
  size_t spart_offset = 0;
  size_t gpart_offset = 0;
  size_t bpart_offset = 0;

  for(int i = 0; i < nr_nodes; i++) {
    const size_t c_ind = sending ? engine_rank * nr_nodes + i:
      i * nr_nodes + engine_rank;

    /* No need to log the local particles. */
    if (i == engine_rank) {
      part_offset += counts[c_ind];
      spart_offset += s_counts[c_ind];
      gpart_offset += g_counts[c_ind];
      bpart_offset += b_counts[c_ind];
      continue;
    }

Loic Hausammann's avatar
Loic Hausammann committed
881
882
    const enum logger_special_flags receive_or_send =
      sending? logger_flag_mpi_exit : logger_flag_mpi_enter;
883
    const int flag = logger_generate_flag(
Loic Hausammann's avatar
Loic Hausammann committed
884
      receive_or_send, i);
885
886

    const unsigned int mask_hydro =
Loic Hausammann's avatar
Loic Hausammann committed
887
      logger_masks_all_part |
888
889
890
891
892
893
894
895
896
897
898
      logger_mask_data[logger_special_flags].mask;

    /* Log the hydro parts. */
    for(int j = 0; j < counts[c_ind]; j++) {
      size_t ind = part_offset + j;
      logger_log_part(log, &parts[ind], mask_hydro,
                      &xparts[ind].logger_data.last_offset,
                      flag);
      xparts[ind].logger_data.steps_since_last_output = 0;
    }

Loic Hausammann's avatar
Loic Hausammann committed
899
    const unsigned int mask_stars = logger_masks_all_spart |
900
901
902
903
904
905
906
907
908
909
910
911
      logger_mask_data[logger_special_flags].mask;

    /* Log the stellar parts. */
    for(int j = 0; j < s_counts[c_ind]; j++) {
      size_t ind = spart_offset + j;
      logger_log_spart(log, &sparts[ind], mask_stars,
                       &sparts[ind].logger_data.last_offset,
                       flag);
      sparts[ind].logger_data.steps_since_last_output = 0;
    }

    const unsigned int mask_grav =
Loic Hausammann's avatar
Loic Hausammann committed
912
      logger_masks_all_gpart |
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
      logger_mask_data[logger_special_flags].mask;

    /* Log the gparts */
    for(int j = 0; j < g_counts[c_ind]; j++) {
      size_t ind = gpart_offset + j;
      /* Log only the dark matter */
      if (gparts[ind].type != swift_type_dark_matter) continue;

      logger_log_gpart(log, &gparts[ind], mask_grav,
                       &gparts[ind].logger_data.last_offset,
                       flag);
      gparts[ind].logger_data.steps_since_last_output = 0;
    }

    /* Log the bparts */
    if (b_counts[c_ind] > 0) {
      error("TODO");
    }

    /* Update the counters */
    part_offset += counts[c_ind];
    spart_offset += s_counts[c_ind];
    gpart_offset += g_counts[c_ind];
    bpart_offset += b_counts[c_ind];
  }
938
939
940
}
#endif

Loic Hausammann's avatar
Loic Hausammann committed
941
942
943
944
945
946
947
948
949
950
951
/**
 * @brief Write a swift_params struct to the given FILE as a stream of bytes.
 *
 * @param log the struct
 * @param stream the file stream
 */
void logger_struct_dump(const struct logger_writer *log, FILE *stream) {
  restart_write_blocks((void *)log, sizeof(struct logger_writer), 1, stream,
                       "logger", "logger");
}

Loic Hausammann's avatar
Loic Hausammann committed
952

Loic Hausammann's avatar
Loic Hausammann committed
953
954
955
956
957
958
959
960
961
962
963
964
965
966
/**
 * @brief Restore a logger struct from the given FILE as a stream of
 * bytes.
 *
 * @param logger the struct
 * @param stream the file stream
 */
void logger_struct_restore(struct logger_writer *log, FILE *stream) {
  /* Read the block */
  restart_read_blocks((void *)log, sizeof(struct logger_writer), 1, stream,
                      NULL, "logger");

  /* generate dump filename */
  char logger_name_file[PARSER_MAX_LINE_SIZE];
967
  logger_get_dump_name(log, logger_name_file);
Loic Hausammann's avatar
Loic Hausammann committed
968

969
  dump_restart(&log->dump, logger_name_file);
Loic Hausammann's avatar
Loic Hausammann committed
970
971
}

lhausamm's avatar
lhausamm committed
972
973
#endif /* WITH_LOGGER */

974
#endif /* HAVE_POSIX_FALLOCATE */