logger.c 30.6 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
    /* Flag for special cases (e.g. change of MPI rank, star formation, ...) */
81
    {sizeof(uint32_t), 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++) {
184
185
    logger_log_part(log, &s->parts[i], &s->xparts[i],
                    logger_masks_all_part,
Loic Hausammann's avatar
Loic Hausammann committed
186
                    /* Special flags */ 0);
lhausamm's avatar
lhausamm committed
187
  }
lhausamm's avatar
lhausamm committed
188

Loic Hausammann's avatar
Loic Hausammann committed
189
190
191
192
193
  /* 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
194
    logger_log_gpart(log, &s->gparts[i], logger_masks_all_gpart,
Loic Hausammann's avatar
Loic Hausammann committed
195
196
197
198
199
                     /* Special flags */ 0);
  }

  /* loop over all sparts */
  for (size_t i = 0; i < s->nr_sparts; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
200
    logger_log_spart(log, &s->sparts[i], logger_masks_all_spart,
Loic Hausammann's avatar
Loic Hausammann committed
201
202
                     /* Special flags */ 0);
  }
lhausamm's avatar
lhausamm committed
203

Loic Hausammann's avatar
Loic Hausammann committed
204
  if (e->total_nr_bparts > 0) error("Not implemented");
lhausamm's avatar
lhausamm committed
205
206
}

207
/**
Loic Hausammann's avatar
Loic Hausammann committed
208
 * @brief Copy the particle fields into a given buffer.
209
 *
Loic Hausammann's avatar
Loic Hausammann committed
210
211
212
213
214
215
 * @param p The #part to copy.
 * @param mask The mask for the fields to write.
 * @param offset The offset to the previous log.
 * @param offset_new The offset of the current record.
 * @param buff The buffer to use when writing.
 * @param special_flags The data for the special flags.
216
 */
Loic Hausammann's avatar
Loic Hausammann committed
217
218
219
void logger_copy_part_fields(
    const struct part *p, unsigned int mask,
    size_t *offset, size_t offset_new, char *buff,
220
    const uint32_t special_flags) {
221
222

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

  /* Write the header. */
lhausamm's avatar
lhausamm committed
227
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
228
229

  /* Particle position as three doubles. */
230
  if (mask & logger_mask_data[logger_x].mask) {
231
232
    memcpy(buff, p->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
233
234
235
  }

  /* Particle velocity as three floats. */
236
  if (mask & logger_mask_data[logger_v].mask) {
237
238
    memcpy(buff, p->v, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
239
240
241
  }

  /* Particle accelleration as three floats. */
242
  if (mask & logger_mask_data[logger_a].mask) {
243
244
    memcpy(buff, p->a_hydro, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
245
246
  }

247
248
#if defined(GADGET2_SPH)

249
  /* Particle internal energy as a single float. */
250
  if (mask & logger_mask_data[logger_u].mask) {
251
252
    memcpy(buff, &p->entropy, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
253
254
255
  }

  /* Particle smoothing length as a single float. */
256
  if (mask & logger_mask_data[logger_h].mask) {
257
258
    memcpy(buff, &p->h, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
259
260
261
  }

  /* Particle density as a single float. */
262
  if (mask & logger_mask_data[logger_rho].mask) {
263
264
    memcpy(buff, &p->rho, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
265
266
267
  }

  /* Particle constants, which is a bit more complicated. */
268
  if (mask & logger_mask_data[logger_consts].mask) {
269
    // TODO make it dependent of logger_mask_data
270
271
    memcpy(buff, &p->mass, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
272
273
274
    const int64_t id = p->id;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
275
276
  }

277
278
#endif

Loic Hausammann's avatar
Loic Hausammann committed
279
280
281
282
283
284
285
286
287
  /* 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;
  }

}

/**
Loic Hausammann's avatar
Loic Hausammann committed
288
 * @brief Dump a #part to the log.
Loic Hausammann's avatar
Loic Hausammann committed
289
290
 *
 * @param log The #logger_writer
Loic Hausammann's avatar
Loic Hausammann committed
291
 * @param p The #part to dump.
292
 * @param xp The #xpart to dump.
Loic Hausammann's avatar
Loic Hausammann committed
293
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Loic Hausammann committed
294
 * @param special_flags The value of the special flag.
Loic Hausammann's avatar
Loic Hausammann committed
295
 */
Loic Hausammann's avatar
Loic Hausammann committed
296
void logger_log_part(struct logger_writer *log, const struct part *p,
297
                     struct xpart *xp, unsigned int mask,
298
                     const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
299

300
301
  logger_log_parts(log, p, xp, /* count */ 1, mask,
                   special_flags);
Loic Hausammann's avatar
Loic Hausammann committed
302
303
304
305
306
307
308
309
310
311
312
313
}

/**
 * @brief Dump a group of #part to the log.
 *
 * @param log The #logger_writer
 * @param sp The #part to dump.
 * @param mask The mask of the data to dump.
 * @param count The number of particle to dump.
 * @param special_flags The value of the special flags.
 */
void logger_log_parts(struct logger_writer *log, const struct part *p,
314
315
                      struct xpart *xp, int count,  unsigned int mask,
                      const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
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
  /* 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, count * size, &offset_new);

  for(int i = 0; i < count; i++) {
    /* Copy everything into the buffer */
    logger_copy_part_fields(&p[i], mask, &xp[i].logger_data.last_offset,
                            offset_new, buff, special_flags);

    /* Update the pointers */
    xp[i].logger_data.last_offset = offset_new;
    xp[i].logger_data.steps_since_last_output = 0;
    buff += size;
    offset_new += size;
  }
}

/**
 * @brief Copy the particle fields into a given buffer.
 *
 * @param sp The #spart to copy.
 * @param mask The mask for the fields to write.
 * @param offset The offset to the previous log.
 * @param offset_new The offset of the current record.
 * @param buff The buffer to use when writing.
 * @param special_flags The data for the special flags.
 */
void logger_copy_spart_fields(
    const struct spart *sp, unsigned int mask,
    size_t *offset, size_t offset_new, char *buff,
349
    const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
350
351
352
353
354

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

Loic Hausammann's avatar
Loic Hausammann committed
355
  /* Make sure we're not looging fields not supported by sparts. */
Loic Hausammann's avatar
Loic Hausammann committed
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
  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.");

  /* 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;
  }
391
}
392
393

/**
Loic Hausammann's avatar
Loic Hausammann committed
394
 * @brief Dump a #spart to the log.
395
 *
Loic Hausammann's avatar
Loic Hausammann committed
396
 * @param log The #logger_writer
Loic Hausammann's avatar
Loic Hausammann committed
397
 * @param sp The #spart to dump.
398
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Loic Hausammann committed
399
 * @param special_flags The value of the special flag.
400
 */
401
402
void logger_log_spart(struct logger_writer *log, struct spart *sp,
                      unsigned int mask, const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
403

404
405
  logger_log_sparts(log, sp, /* count */ 1, mask,
                    special_flags);
Loic Hausammann's avatar
Loic Hausammann committed
406
407
408
409
410
411
412
413
414
415
416
417
}

/**
 * @brief Dump a group of #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 count The number of particle to dump.
 * @param special_flags The value of the special flags.
 */
void logger_log_sparts(struct logger_writer *log, struct spart *sp,
418
419
                       int count, unsigned int mask,
                       const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  /* 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, count * size, &offset_new);

  for(int i = 0; i < count; i++) {
    /* Copy everything into the buffer */
    logger_copy_spart_fields(&sp[i], mask, &sp[i].logger_data.last_offset,
                             offset_new, buff, special_flags);

    /* Update the pointers */
    sp[i].logger_data.last_offset = offset_new;
    sp[i].logger_data.steps_since_last_output = 0;
    buff += size;
    offset_new += size;
  }
}

/**
 * @brief Copy the particle fields into a given buffer.
 *
 * @param gp The #gpart to copy.
 * @param mask The mask for the fields to write.
 * @param offset The offset to the previous log.
 * @param offset_new The offset of the current record.
 * @param buff The buffer to use when writing.
 * @param special_flags The data of the special flag.
 */
void logger_copy_gpart_fields(
    const struct gpart *gp, unsigned int mask,
    size_t *offset, size_t offset_new, char *buff,
453
    const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
454

Loic Hausammann's avatar
Loic Hausammann committed
455
#ifdef SWIFT_DEBUG_CHECKS
Loic Hausammann's avatar
Loic Hausammann committed
456
  if (gp->id_or_neg_offset < 0) {
Loic Hausammann's avatar
Loic Hausammann committed
457
458
459
    error("Cannot log a gpart attached to another particle");
  }
#endif
460
461

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

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

  /* Write the header. */
lhausamm's avatar
lhausamm committed
471
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
472
473

  /* Particle position as three doubles. */
474
  if (mask & logger_mask_data[logger_x].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
475
    memcpy(buff, gp->x, logger_mask_data[logger_x].size);
476
    buff += logger_mask_data[logger_x].size;
477
478
479
  }

  /* Particle velocity as three floats. */
480
  if (mask & logger_mask_data[logger_v].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
481
    memcpy(buff, gp->v_full, logger_mask_data[logger_v].size);
482
    buff += logger_mask_data[logger_v].size;
483
484
485
  }

  /* Particle accelleration as three floats. */
486
  if (mask & logger_mask_data[logger_a].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
487
    memcpy(buff, gp->a_grav, logger_mask_data[logger_a].size);
488
    buff += logger_mask_data[logger_a].size;
489
490
491
  }

  /* Particle constants, which is a bit more complicated. */
492
  if (mask & logger_mask_data[logger_consts].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
493
    // TODO make it dependent of logger_mask_data.
Loic Hausammann's avatar
Loic Hausammann committed
494
    memcpy(buff, &gp->mass, sizeof(float));
495
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
496
    const int64_t id = gp->id_or_neg_offset;
Loic Hausammann's avatar
Loic Hausammann committed
497
498
499
500
501
502
503
504
    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;
505
506
  }

Loic Hausammann's avatar
Loic Hausammann committed
507
508
509
510
511
512
513
514
515
516
}

/**
 * @brief Dump a #gpart to the log.
 *
 * @param log The #logger_writer
 * @param p The #gpart to dump.
 * @param mask The mask of the data to dump.
 * @param special_flags The value of the special flags.
 */
517
518
519
void logger_log_gpart(struct logger_writer *log, struct gpart *p,
                      unsigned int mask, const uint32_t special_flags) {
  logger_log_gparts(log, p, /* count */ 1, mask, special_flags);
520
521
}

Loic Hausammann's avatar
Loic Hausammann committed
522
523
524
525
526
527
528
529
530
531
/**
 * @brief Dump a group of #gpart to the log.
 *
 * @param log The #logger_writer
 * @param p The #gpart to dump.
 * @param mask The mask of the data to dump.
 * @param count The number of particle to dump.
 * @param special_flags The value of the special flags.
 */
void logger_log_gparts(struct logger_writer *log, struct gpart *p,
532
533
                       int count, unsigned int mask,
                       const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  /* 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, count * size, &offset_new);

  for(int i = 0; i < count; i++) {
    /* Log only the dark matter */
    if (p[i].type != swift_type_dark_matter) continue;

    /* Copy everything into the buffer */
    logger_copy_gpart_fields(&p[i], mask, &p[i].logger_data.last_offset,
                             offset_new, buff, special_flags);

    /* Update the pointers */
    p[i].logger_data.last_offset = offset_new;
    p[i].logger_data.steps_since_last_output = 0;
    buff += size;
    offset_new += size;
  }
}

lhausamm's avatar
lhausamm committed
557
558
559
/**
 * @brief write a timestamp
 *
Loic Hausammann's avatar
Loic Hausammann committed
560
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
561
 * @param timestamp time to write
562
 * @param time time or scale factor
Loic Hausammann's avatar
Format    
Loic Hausammann committed
563
564
 * @param offset Pointer to the offset of the previous log of this particle;
 * (return) offset of this log.
lhausamm's avatar
lhausamm committed
565
 */
Loic Hausammann's avatar
Loic Hausammann committed
566
void logger_log_timestamp(struct logger_writer *log, integertime_t timestamp,
567
                          double time, size_t *offset) {
568
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
569

570
  /* Start by computing the size of the message. */
571
572
  const int size =
      logger_compute_chunk_size(logger_mask_data[logger_timestamp].mask);
573
574
575

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

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

582
  /* Store the timestamp. */
Loic Hausammann's avatar
Loic Hausammann committed
583
  // TODO make it dependent of logger_mask_data.
584
  memcpy(buff, &timestamp, sizeof(integertime_t));
585
586
  buff += sizeof(integertime_t);

Loic Hausammann's avatar
Loic Hausammann committed
587
  /* Store the time. */
588
  memcpy(buff, &time, sizeof(double));
589
590
591
592

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

lhausamm's avatar
lhausamm committed
594
/**
lhausamm's avatar
lhausamm committed
595
 * @brief Ensure that the buffer is large enough for a step.
lhausamm's avatar
lhausamm committed
596
597
 *
 * Check if logger parameters are large enough to write all particles
lhausamm's avatar
lhausamm committed
598
 * and ensure that enough space is available in the buffer.
lhausamm's avatar
lhausamm committed
599
 *
Loic Hausammann's avatar
Loic Hausammann committed
600
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
601
602
603
 * @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
604
 */
Loic Hausammann's avatar
Loic Hausammann committed
605
void logger_ensure_size(struct logger_writer *log, size_t total_nr_parts,
Loic Hausammann's avatar
Format    
Loic Hausammann committed
606
                        size_t total_nr_gparts, size_t total_nr_sparts) {
lhausamm's avatar
lhausamm committed
607

Loic Hausammann's avatar
Loic Hausammann committed
608
609
  /* count part memory */
  size_t limit = 0;
lhausamm's avatar
lhausamm committed
610

Loic Hausammann's avatar
Loic Hausammann committed
611
612
  /* count part memory */
  limit += total_nr_parts;
lhausamm's avatar
lhausamm committed
613

Loic Hausammann's avatar
Loic Hausammann committed
614
615
  /* count gpart memory */
  limit += total_nr_gparts;
616

Loic Hausammann's avatar
Loic Hausammann committed
617
  /* count spart memory. */
Loic Hausammann's avatar
Loic Hausammann committed
618
  limit += total_nr_sparts;
lhausamm's avatar
lhausamm committed
619

Loic Hausammann's avatar
Loic Hausammann committed
620
621
622
623
  // TODO improve estimate with the size of each particle
  limit *= log->max_chunk_size;

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

627
628
629
630
631
632
633
634
635
/** @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
636
637
638
/**
 * @brief intialize the logger structure
 *
Loic Hausammann's avatar
Loic Hausammann committed
639
 * @param log The #logger_writer
640
 * @param params The #swift_params
lhausamm's avatar
lhausamm committed
641
 */
Loic Hausammann's avatar
Loic Hausammann committed
642
643
void logger_init(struct logger_writer *log, struct swift_params *params) {
  /* read parameters. */
lhausamm's avatar
lhausamm committed
644
  log->delta_step = parser_get_param_int(params, "Logger:delta_step");
Loic Hausammann's avatar
Loic Hausammann committed
645
  size_t buffer_size =
Loic Hausammann's avatar
Loic Hausammann committed
646
647
      parser_get_opt_param_float(params, "Logger:initial_buffer_size", 0.5) *
      1e9;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
648
  log->buffer_scale =
649
      parser_get_opt_param_float(params, "Logger:buffer_scale", 10);
lhausamm's avatar
lhausamm committed
650
651
  parser_get_param_string(params, "Logger:basename", log->base_name);

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

Loic Hausammann's avatar
Loic Hausammann committed
655
  /* set initial value of parameters. */
lhausamm's avatar
lhausamm committed
656
  log->timestamp_offset = 0;
Loic Hausammann's avatar
Loic Hausammann committed
657
  log->index.dump_size_last_output = 0;
lhausamm's avatar
lhausamm committed
658

Loic Hausammann's avatar
Loic Hausammann committed
659
  /* generate dump filename. */
lhausamm's avatar
lhausamm committed
660
  char logger_name_file[PARSER_MAX_LINE_SIZE];
661
  logger_get_dump_name(log, logger_name_file);
lhausamm's avatar
lhausamm committed
662

Loic Hausammann's avatar
Loic Hausammann committed
663
  /* Compute max size for a particle chunk. */
664
665
  int max_size = logger_offset_size + logger_mask_size;

Loic Hausammann's avatar
Loic Hausammann committed
666
  /* Loop over all fields except timestamp. */
667
668
669
670
  for (int i = 0; i < logger_count_mask - 1; i++) {
    max_size += logger_mask_data[i].size;
  }
  log->max_chunk_size = max_size;
671

Loic Hausammann's avatar
Loic Hausammann committed
672
  /* init dump. */
673
  dump_init(&log->dump, logger_name_file, buffer_size);
lhausamm's avatar
lhausamm committed
674
675
676
677
678
}

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

683
684
685
/**
 * @brief Write a file header to a logger file
 *
Loic Hausammann's avatar
Loic Hausammann committed
686
 * @param log The #logger_writer
687
688
 *
 */
Loic Hausammann's avatar
Loic Hausammann committed
689
void logger_write_file_header(struct logger_writer *log) {
lhausamm's avatar
lhausamm committed
690

Loic Hausammann's avatar
Loic Hausammann committed
691
  /* get required variables. */
692
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
693

Loic Hausammann's avatar
Loic Hausammann committed
694
  uint64_t file_offset = dump->file_offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
695

lhausamm's avatar
lhausamm committed
696
  if (file_offset != 0)
Loic Hausammann's avatar
Format    
Loic Hausammann committed
697
698
699
    error(
        "The logger is not empty."
        "This function should be called before writing anything in the logger");
700

Loic Hausammann's avatar
Loic Hausammann committed
701
  /* Write format information. */
Loic Hausammann's avatar
Loic Hausammann committed
702
703
  logger_write_data(dump, &file_offset, logger_format_size,
                    &logger_file_format);
Loic Hausammann's avatar
Loic Hausammann committed
704

Loic Hausammann's avatar
Loic Hausammann committed
705
  /* Write the major version number. */
Loic Hausammann's avatar
Loic Hausammann committed
706
707
708
  int major = logger_major_version;
  logger_write_data(dump, &file_offset, sizeof(int), &major);

Loic Hausammann's avatar
Loic Hausammann committed
709
  /* Write the minor version number. */
Loic Hausammann's avatar
Loic Hausammann committed
710
711
  int minor = logger_minor_version;
  logger_write_data(dump, &file_offset, sizeof(int), &minor);
Loic Hausammann's avatar
Format    
Loic Hausammann committed
712

Loic Hausammann's avatar
Loic Hausammann committed
713
  /* write offset direction. */
714
  const int reversed = 0;
715
  logger_write_data(dump, &file_offset, sizeof(int), &reversed);
lhausamm's avatar
lhausamm committed
716

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

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

Loic Hausammann's avatar
Loic Hausammann committed
724
  /* write number of masks. */
725
726
  const unsigned int count_mask = logger_count_mask;
  logger_write_data(dump, &file_offset, sizeof(unsigned int), &count_mask);
727

Loic Hausammann's avatar
Loic Hausammann committed
728
729
  /* write masks. */
  // loop over all mask type.
730
  for (int i = 0; i < logger_count_mask; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
731
    // mask name.
732
    logger_write_data(dump, &file_offset, logger_label_size,
733
                      &logger_mask_data[i].name);
734

Loic Hausammann's avatar
Loic Hausammann committed
735
    // mask size.
736
    logger_write_data(dump, &file_offset, sizeof(unsigned int),
737
                      &logger_mask_data[i].size);
738
  }
739

Loic Hausammann's avatar
Loic Hausammann committed
740
  /* last step: write first offset. */
741
  memcpy(skip_header, &file_offset, logger_offset_size);
lhausamm's avatar
lhausamm committed
742
}
743

lhausamm's avatar
lhausamm committed
744
745
746
747
748
/**
 * @brief read chunk header
 *
 * @param buff The reading buffer
 * @param mask The mask to read
lhausamm's avatar
lhausamm committed
749
 * @param offset (return) the offset pointed by this chunk (absolute)
Loic Hausammann's avatar
Loic Hausammann committed
750
 * @param cur_offset The current chunk offset
lhausamm's avatar
lhausamm committed
751
752
753
 *
 * @return Number of bytes read
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
754
755
__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
756
757
  memcpy(mask, buff, logger_mask_size);
  buff += logger_mask_size;
lhausamm's avatar
lhausamm committed
758
759

  *offset = 0;
lhausamm's avatar
lhausamm committed
760
  memcpy(offset, buff, logger_offset_size);
lhausamm's avatar
lhausamm committed
761
  *offset = cur_offset - *offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
762

lhausamm's avatar
lhausamm committed
763
  return logger_mask_size + logger_offset_size;
lhausamm's avatar
lhausamm committed
764
765
}

Pedro Gonnet's avatar
Pedro Gonnet committed
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
/**
 * @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
782
783
784
  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
785
786

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

  /* Particle position as three doubles. */
791
  if (mask & logger_mask_data[logger_x].mask) {
792
793
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
794
795
796
  }

  /* Particle velocity as three floats. */
797
  if (mask & logger_mask_data[logger_v].mask) {
798
799
    memcpy(p->v, buff, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
800
801
802
  }

  /* Particle accelleration as three floats. */
803
  if (mask & logger_mask_data[logger_a].mask) {
804
805
    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
806
807
  }

808
809
#if defined(GADGET2_SPH)

Pedro Gonnet's avatar
Pedro Gonnet committed
810
  /* Particle internal energy as a single float. */
811
  if (mask & logger_mask_data[logger_u].mask) {
812
813
    memcpy(&p->entropy, buff, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
814
815
816
  }

  /* Particle smoothing length as a single float. */
817
  if (mask & logger_mask_data[logger_h].mask) {
818
819
    memcpy(&p->h, buff, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
820
821
822
  }

  /* Particle density as a single float. */
823
  if (mask & logger_mask_data[logger_rho].mask) {
824
825
    memcpy(&p->rho, buff, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
826
827
828
  }

  /* Particle constants, which is a bit more complicated. */
829
  if (mask & logger_mask_data[logger_rho].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
830
    // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
831
832
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
833
834
835
836
    int64_t id = 0;
    memcpy(&id, buff, sizeof(int64_t));
    p->id = id;
    buff += sizeof(int64_t);
Pedro Gonnet's avatar
Pedro Gonnet committed
837
838
  }

839
840
#endif

Pedro Gonnet's avatar
Pedro Gonnet committed
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
  /* 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
861
862
863
  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
864
865

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

Pedro Gonnet's avatar
Pedro Gonnet committed
869
  /* We can't store all part fields in a gpart. */
870
871
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask))
Pedro Gonnet's avatar
Pedro Gonnet committed
872
873
874
    error("Trying to read SPH quantities into a gpart.");

  /* Particle position as three doubles. */
875
  if (mask & logger_mask_data[logger_x].mask) {
876
877
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
878
879
880
  }

  /* Particle velocity as three floats. */
881
  if (mask & logger_mask_data[logger_v].mask) {
882
883
    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
884
885
886
  }

  /* Particle accelleration as three floats. */
887
  if (mask & logger_mask_data[logger_a].mask) {
888
889
    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
890
891
892
  }

  /* Particle constants, which is a bit more complicated. */
893
  if (mask & logger_mask_data[logger_rho].mask) {
894
    // TODO make it dependent of logger_mask_data
Pedro Gonnet's avatar
Pedro Gonnet committed
895
896
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
897
898
899
    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
900
901
902
903
904
905
906
907
908
909
  }

  /* 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
910
 * @param time The time in which to store the value.
Pedro Gonnet's avatar
Pedro Gonnet committed
911
912
913
914
915
916
 * @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.
 */
917
918
int logger_read_timestamp(unsigned long long int *t, double *time,
                          size_t *offset, const char *buff) {
Pedro Gonnet's avatar
Pedro Gonnet committed
919
920
921
922
923

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

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
924
925
926
  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
927
928

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

Pedro Gonnet's avatar
Pedro Gonnet committed
932
  /* Make sure we don't have extra fields. */
933
  if (mask != logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
934
935
936
    error("Timestamp message contains extra fields.");

  /* Copy the timestamp value from the buffer. */
Loic Hausammann's avatar
Loic Hausammann committed
937
  // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
938
  memcpy(t, buff, sizeof(unsigned long long int));
939
940
941
  buff += sizeof(unsigned long long int);

  /* Copy the timestamp value from the buffer. */
942
  memcpy(time, buff, sizeof(double));
Pedro Gonnet's avatar
Pedro Gonnet committed
943
944
945
946

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

948

Loic Hausammann's avatar
Loic Hausammann committed
949
950
951
952
953
954
955
956
957
958
959
/**
 * @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
960

Loic Hausammann's avatar
Loic Hausammann committed
961
962
963
964
965
966
967
968
969
970
971
972
973
974
/**
 * @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];
975
  logger_get_dump_name(log, logger_name_file);
Loic Hausammann's avatar
Loic Hausammann committed
976