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++) {
Loic Hausammann's avatar
Format    
Loic Hausammann committed
184
    logger_log_part(log, &s->parts[i], &s->xparts[i], logger_masks_all_part,
Loic Hausammann's avatar
Loic Hausammann committed
185
                    /* Special flags */ 0);
lhausamm's avatar
lhausamm committed
186
  }
lhausamm's avatar
lhausamm committed
187

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

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

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

206
/**
Loic Hausammann's avatar
Loic Hausammann committed
207
 * @brief Copy the particle fields into a given buffer.
208
 *
Loic Hausammann's avatar
Loic Hausammann committed
209
210
211
212
213
214
 * @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.
215
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
216
217
218
void logger_copy_part_fields(const struct part *p, unsigned int mask,
                             size_t *offset, size_t offset_new, char *buff,
                             const uint32_t special_flags) {
219
220

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

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

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

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

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

245
246
#if defined(GADGET2_SPH)

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

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

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

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

275
276
#endif

Loic Hausammann's avatar
Loic Hausammann committed
277
278
279
280
281
282
283
284
  /* 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
285
 * @brief Dump a #part to the log.
Loic Hausammann's avatar
Loic Hausammann committed
286
287
 *
 * @param log The #logger_writer
Loic Hausammann's avatar
Loic Hausammann committed
288
 * @param p The #part to dump.
289
 * @param xp The #xpart to dump.
Loic Hausammann's avatar
Loic Hausammann committed
290
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Loic Hausammann committed
291
 * @param special_flags The value of the special flag.
Loic Hausammann's avatar
Loic Hausammann committed
292
 */
Loic Hausammann's avatar
Loic Hausammann committed
293
void logger_log_part(struct logger_writer *log, const struct part *p,
294
                     struct xpart *xp, unsigned int mask,
295
                     const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
296

Loic Hausammann's avatar
Format    
Loic Hausammann committed
297
  logger_log_parts(log, p, xp, /* count */ 1, mask, special_flags);
Loic Hausammann's avatar
Loic Hausammann committed
298
299
300
301
302
303
304
305
306
307
308
309
}

/**
 * @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,
Loic Hausammann's avatar
Format    
Loic Hausammann committed
310
                      struct xpart *xp, int count, unsigned int mask,
311
                      const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
312
313
314
315
316
317
318
  /* 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);

Loic Hausammann's avatar
Format    
Loic Hausammann committed
319
  for (int i = 0; i < count; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
    /* 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.
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
342
343
344
void logger_copy_spart_fields(const struct spart *sp, unsigned int mask,
                              size_t *offset, size_t offset_new, char *buff,
                              const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
345
346
347
348
349

  /* 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
350
  /* Make sure we're not looging fields not supported by sparts. */
Loic Hausammann's avatar
Loic Hausammann committed
351
352
353
354
355
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
  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;
  }
386
}
387
388

/**
Loic Hausammann's avatar
Loic Hausammann committed
389
 * @brief Dump a #spart to the log.
390
 *
Loic Hausammann's avatar
Loic Hausammann committed
391
 * @param log The #logger_writer
Loic Hausammann's avatar
Loic Hausammann committed
392
 * @param sp The #spart to dump.
393
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Loic Hausammann committed
394
 * @param special_flags The value of the special flag.
395
 */
396
397
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
398

Loic Hausammann's avatar
Format    
Loic Hausammann committed
399
  logger_log_sparts(log, sp, /* count */ 1, mask, special_flags);
Loic Hausammann's avatar
Loic Hausammann committed
400
401
402
403
404
405
406
407
408
409
410
}

/**
 * @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.
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
411
412
void logger_log_sparts(struct logger_writer *log, struct spart *sp, int count,
                       unsigned int mask, const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
413
414
415
416
417
418
419
  /* 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);

Loic Hausammann's avatar
Format    
Loic Hausammann committed
420
  for (int i = 0; i < count; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    /* 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.
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
443
444
445
void logger_copy_gpart_fields(const struct gpart *gp, unsigned int mask,
                              size_t *offset, size_t offset_new, char *buff,
                              const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
446

Loic Hausammann's avatar
Loic Hausammann committed
447
#ifdef SWIFT_DEBUG_CHECKS
Loic Hausammann's avatar
Loic Hausammann committed
448
  if (gp->id_or_neg_offset < 0) {
Loic Hausammann's avatar
Loic Hausammann committed
449
450
451
    error("Cannot log a gpart attached to another particle");
  }
#endif
452
453

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

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

  /* Write the header. */
lhausamm's avatar
lhausamm committed
463
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
464
465

  /* Particle position as three doubles. */
466
  if (mask & logger_mask_data[logger_x].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
467
    memcpy(buff, gp->x, logger_mask_data[logger_x].size);
468
    buff += logger_mask_data[logger_x].size;
469
470
471
  }

  /* Particle velocity as three floats. */
472
  if (mask & logger_mask_data[logger_v].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
473
    memcpy(buff, gp->v_full, logger_mask_data[logger_v].size);
474
    buff += logger_mask_data[logger_v].size;
475
476
477
  }

  /* Particle accelleration as three floats. */
478
  if (mask & logger_mask_data[logger_a].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
479
    memcpy(buff, gp->a_grav, logger_mask_data[logger_a].size);
480
    buff += logger_mask_data[logger_a].size;
481
482
483
  }

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

/**
 * @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.
 */
508
509
510
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);
511
512
}

Loic Hausammann's avatar
Loic Hausammann committed
513
514
515
516
517
518
519
520
521
/**
 * @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.
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
522
523
void logger_log_gparts(struct logger_writer *log, struct gpart *p, int count,
                       unsigned int mask, const uint32_t special_flags) {
Loic Hausammann's avatar
Loic Hausammann committed
524
525
526
527
528
529
530
  /* 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);

Loic Hausammann's avatar
Format    
Loic Hausammann committed
531
  for (int i = 0; i < count; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    /* 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
547
548
549
/**
 * @brief write a timestamp
 *
Loic Hausammann's avatar
Loic Hausammann committed
550
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
551
 * @param timestamp time to write
552
 * @param time time or scale factor
Loic Hausammann's avatar
Format    
Loic Hausammann committed
553
554
 * @param offset Pointer to the offset of the previous log of this particle;
 * (return) offset of this log.
lhausamm's avatar
lhausamm committed
555
 */
Loic Hausammann's avatar
Loic Hausammann committed
556
void logger_log_timestamp(struct logger_writer *log, integertime_t timestamp,
557
                          double time, size_t *offset) {
558
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
559

560
  /* Start by computing the size of the message. */
561
562
  const int size =
      logger_compute_chunk_size(logger_mask_data[logger_timestamp].mask);
563
564
565

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

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

572
  /* Store the timestamp. */
Loic Hausammann's avatar
Loic Hausammann committed
573
  // TODO make it dependent of logger_mask_data.
574
  memcpy(buff, &timestamp, sizeof(integertime_t));
575
576
  buff += sizeof(integertime_t);

Loic Hausammann's avatar
Loic Hausammann committed
577
  /* Store the time. */
578
  memcpy(buff, &time, sizeof(double));
579
580
581
582

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

lhausamm's avatar
lhausamm committed
584
/**
lhausamm's avatar
lhausamm committed
585
 * @brief Ensure that the buffer is large enough for a step.
lhausamm's avatar
lhausamm committed
586
587
 *
 * Check if logger parameters are large enough to write all particles
lhausamm's avatar
lhausamm committed
588
 * and ensure that enough space is available in the buffer.
lhausamm's avatar
lhausamm committed
589
 *
Loic Hausammann's avatar
Loic Hausammann committed
590
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
591
592
593
 * @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
594
 */
Loic Hausammann's avatar
Loic Hausammann committed
595
void logger_ensure_size(struct logger_writer *log, size_t total_nr_parts,
Loic Hausammann's avatar
Format    
Loic Hausammann committed
596
                        size_t total_nr_gparts, size_t total_nr_sparts) {
lhausamm's avatar
lhausamm committed
597

Loic Hausammann's avatar
Loic Hausammann committed
598
599
  /* count part memory */
  size_t limit = 0;
lhausamm's avatar
lhausamm committed
600

Loic Hausammann's avatar
Loic Hausammann committed
601
602
  /* count part memory */
  limit += total_nr_parts;
lhausamm's avatar
lhausamm committed
603

Loic Hausammann's avatar
Loic Hausammann committed
604
605
  /* count gpart memory */
  limit += total_nr_gparts;
606

Loic Hausammann's avatar
Loic Hausammann committed
607
  /* count spart memory. */
Loic Hausammann's avatar
Loic Hausammann committed
608
  limit += total_nr_sparts;
lhausamm's avatar
lhausamm committed
609

Loic Hausammann's avatar
Loic Hausammann committed
610
611
612
613
  // TODO improve estimate with the size of each particle
  limit *= log->max_chunk_size;

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

617
618
619
620
621
622
623
624
625
/** @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
626
627
628
/**
 * @brief intialize the logger structure
 *
Loic Hausammann's avatar
Loic Hausammann committed
629
 * @param log The #logger_writer
630
 * @param params The #swift_params
lhausamm's avatar
lhausamm committed
631
 */
Loic Hausammann's avatar
Loic Hausammann committed
632
633
void logger_init(struct logger_writer *log, struct swift_params *params) {
  /* read parameters. */
lhausamm's avatar
lhausamm committed
634
  log->delta_step = parser_get_param_int(params, "Logger:delta_step");
Loic Hausammann's avatar
Loic Hausammann committed
635
  size_t buffer_size =
Loic Hausammann's avatar
Loic Hausammann committed
636
637
      parser_get_opt_param_float(params, "Logger:initial_buffer_size", 0.5) *
      1e9;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
638
  log->buffer_scale =
639
      parser_get_opt_param_float(params, "Logger:buffer_scale", 10);
lhausamm's avatar
lhausamm committed
640
641
  parser_get_param_string(params, "Logger:basename", log->base_name);

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

Loic Hausammann's avatar
Loic Hausammann committed
645
  /* set initial value of parameters. */
lhausamm's avatar
lhausamm committed
646
  log->timestamp_offset = 0;
Loic Hausammann's avatar
Loic Hausammann committed
647
  log->index.dump_size_last_output = 0;
lhausamm's avatar
lhausamm committed
648

Loic Hausammann's avatar
Loic Hausammann committed
649
  /* generate dump filename. */
lhausamm's avatar
lhausamm committed
650
  char logger_name_file[PARSER_MAX_LINE_SIZE];
651
  logger_get_dump_name(log, logger_name_file);
lhausamm's avatar
lhausamm committed
652

Loic Hausammann's avatar
Loic Hausammann committed
653
  /* Compute max size for a particle chunk. */
654
655
  int max_size = logger_offset_size + logger_mask_size;

Loic Hausammann's avatar
Loic Hausammann committed
656
  /* Loop over all fields except timestamp. */
657
658
659
660
  for (int i = 0; i < logger_count_mask - 1; i++) {
    max_size += logger_mask_data[i].size;
  }
  log->max_chunk_size = max_size;
661

Loic Hausammann's avatar
Loic Hausammann committed
662
  /* init dump. */
663
  dump_init(&log->dump, logger_name_file, buffer_size);
lhausamm's avatar
lhausamm committed
664
665
666
667
668
}

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

673
674
675
/**
 * @brief Write a file header to a logger file
 *
Loic Hausammann's avatar
Loic Hausammann committed
676
 * @param log The #logger_writer
677
678
 *
 */
Loic Hausammann's avatar
Loic Hausammann committed
679
void logger_write_file_header(struct logger_writer *log) {
lhausamm's avatar
lhausamm committed
680

Loic Hausammann's avatar
Loic Hausammann committed
681
  /* get required variables. */
682
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
683

Loic Hausammann's avatar
Loic Hausammann committed
684
  uint64_t file_offset = dump->file_offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
685

lhausamm's avatar
lhausamm committed
686
  if (file_offset != 0)
Loic Hausammann's avatar
Format    
Loic Hausammann committed
687
688
689
    error(
        "The logger is not empty."
        "This function should be called before writing anything in the logger");
690

Loic Hausammann's avatar
Loic Hausammann committed
691
  /* Write format information. */
Loic Hausammann's avatar
Loic Hausammann committed
692
693
  logger_write_data(dump, &file_offset, logger_format_size,
                    &logger_file_format);
Loic Hausammann's avatar
Loic Hausammann committed
694

Loic Hausammann's avatar
Loic Hausammann committed
695
  /* Write the major version number. */
Loic Hausammann's avatar
Loic Hausammann committed
696
697
698
  int major = logger_major_version;
  logger_write_data(dump, &file_offset, sizeof(int), &major);

Loic Hausammann's avatar
Loic Hausammann committed
699
  /* Write the minor version number. */
Loic Hausammann's avatar
Loic Hausammann committed
700
701
  int minor = logger_minor_version;
  logger_write_data(dump, &file_offset, sizeof(int), &minor);
Loic Hausammann's avatar
Format    
Loic Hausammann committed
702

Loic Hausammann's avatar
Loic Hausammann committed
703
  /* write offset direction. */
704
  const int reversed = 0;
705
  logger_write_data(dump, &file_offset, sizeof(int), &reversed);
lhausamm's avatar
lhausamm committed
706

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

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

Loic Hausammann's avatar
Loic Hausammann committed
714
  /* write number of masks. */
715
716
  const unsigned int count_mask = logger_count_mask;
  logger_write_data(dump, &file_offset, sizeof(unsigned int), &count_mask);
717

Loic Hausammann's avatar
Loic Hausammann committed
718
719
  /* write masks. */
  // loop over all mask type.
720
  for (int i = 0; i < logger_count_mask; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
721
    // mask name.
722
    logger_write_data(dump, &file_offset, logger_label_size,
723
                      &logger_mask_data[i].name);
724

Loic Hausammann's avatar
Loic Hausammann committed
725
    // mask size.
726
    logger_write_data(dump, &file_offset, sizeof(unsigned int),
727
                      &logger_mask_data[i].size);
728
  }
729

Loic Hausammann's avatar
Loic Hausammann committed
730
  /* last step: write first offset. */
731
  memcpy(skip_header, &file_offset, logger_offset_size);
lhausamm's avatar
lhausamm committed
732
}
733

lhausamm's avatar
lhausamm committed
734
735
736
737
738
/**
 * @brief read chunk header
 *
 * @param buff The reading buffer
 * @param mask The mask to read
lhausamm's avatar
lhausamm committed
739
 * @param offset (return) the offset pointed by this chunk (absolute)
Loic Hausammann's avatar
Loic Hausammann committed
740
 * @param cur_offset The current chunk offset
lhausamm's avatar
lhausamm committed
741
742
743
 *
 * @return Number of bytes read
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
744
745
__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
746
747
  memcpy(mask, buff, logger_mask_size);
  buff += logger_mask_size;
lhausamm's avatar
lhausamm committed
748
749

  *offset = 0;
lhausamm's avatar
lhausamm committed
750
  memcpy(offset, buff, logger_offset_size);
lhausamm's avatar
lhausamm committed
751
  *offset = cur_offset - *offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
752

lhausamm's avatar
lhausamm committed
753
  return logger_mask_size + logger_offset_size;
lhausamm's avatar
lhausamm committed
754
755
}

Pedro Gonnet's avatar
Pedro Gonnet committed
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
/**
 * @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
772
773
774
  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
775
776

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

  /* Particle position as three doubles. */
781
  if (mask & logger_mask_data[logger_x].mask) {
782
783
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
784
785
786
  }

  /* Particle velocity as three floats. */
787
  if (mask & logger_mask_data[logger_v].mask) {
788
789
    memcpy(p->v, buff, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
790
791
792
  }

  /* Particle accelleration as three floats. */
793
  if (mask & logger_mask_data[logger_a].mask) {
794
795
    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
796
797
  }

798
799
#if defined(GADGET2_SPH)

Pedro Gonnet's avatar
Pedro Gonnet committed
800
  /* Particle internal energy as a single float. */
801
  if (mask & logger_mask_data[logger_u].mask) {
802
803
    memcpy(&p->entropy, buff, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
804
805
806
  }

  /* Particle smoothing length as a single float. */
807
  if (mask & logger_mask_data[logger_h].mask) {
808
809
    memcpy(&p->h, buff, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
810
811
812
  }

  /* Particle density as a single float. */
813
  if (mask & logger_mask_data[logger_rho].mask) {
814
815
    memcpy(&p->rho, buff, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
816
817
818
  }

  /* Particle constants, which is a bit more complicated. */
819
  if (mask & logger_mask_data[logger_rho].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
820
    // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
821
822
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
823
824
825
826
    int64_t id = 0;
    memcpy(&id, buff, sizeof(int64_t));
    p->id = id;
    buff += sizeof(int64_t);
Pedro Gonnet's avatar
Pedro Gonnet committed
827
828
  }

829
830
#endif

Pedro Gonnet's avatar
Pedro Gonnet committed
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
  /* 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
851
852
853
  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
854
855

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

Pedro Gonnet's avatar
Pedro Gonnet committed
859
  /* We can't store all part fields in a gpart. */
860
861
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask))
Pedro Gonnet's avatar
Pedro Gonnet committed
862
863
864
    error("Trying to read SPH quantities into a gpart.");

  /* Particle position as three doubles. */
865
  if (mask & logger_mask_data[logger_x].mask) {
866
867
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
868
869
870
  }

  /* Particle velocity as three floats. */
871
  if (mask & logger_mask_data[logger_v].mask) {
872
873
    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
874
875
876
  }

  /* Particle accelleration as three floats. */
877
  if (mask & logger_mask_data[logger_a].mask) {
878
879
    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
880
881
882
  }

  /* Particle constants, which is a bit more complicated. */
883
  if (mask & logger_mask_data[logger_rho].mask) {
884
    // TODO make it dependent of logger_mask_data
Pedro Gonnet's avatar
Pedro Gonnet committed
885
886
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
887
888
889
    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
890
891
892
893
894
895
896
897
898
899
  }

  /* 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
900
 * @param time The time in which to store the value.
Pedro Gonnet's avatar
Pedro Gonnet committed
901
902
903
904
905
906
 * @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.
 */
907
908
int logger_read_timestamp(unsigned long long int *t, double *time,
                          size_t *offset, const char *buff) {
Pedro Gonnet's avatar
Pedro Gonnet committed
909
910
911
912
913

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

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
914
915
916
  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
917
918

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

Pedro Gonnet's avatar
Pedro Gonnet committed
922
  /* Make sure we don't have extra fields. */
923
  if (mask != logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
924
925
926
    error("Timestamp message contains extra fields.");

  /* Copy the timestamp value from the buffer. */
Loic Hausammann's avatar
Loic Hausammann committed
927
  // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
928
  memcpy(t, buff, sizeof(unsigned long long int));
929
930
931
  buff += sizeof(unsigned long long int);

  /* Copy the timestamp value from the buffer. */
932
  memcpy(time, buff, sizeof(double));
Pedro Gonnet's avatar
Pedro Gonnet committed
933
934
935
936

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

Loic Hausammann's avatar
Loic Hausammann committed
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
/**
 * @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");
}

/**
 * @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];
963
  logger_get_dump_name(log, logger_name_file);