Commit 0b43546a authored by Loic Hausammann's avatar Loic Hausammann
Browse files

First review

parent ff07663e
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* 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/>.
*
******************************************************************************/
#include "logger_header.h"
#include "logger_io.h"
......@@ -8,29 +26,29 @@
#include <string.h>
/**
* @brief print a header struct
* @brief Print the properties of the header to stdout.
*
* @param h The #header
* @param h The #header.
*/
void header_print(const struct header *h) {
#ifdef SWIFT_DEBUG_CHECKS
printf("Debug checks enabled\n");
message("Debug checks enabled\n");
#endif
printf("Version: %s\n", h->version);
printf("First Offset: %lu\n", h->offset_first);
message("Version: %s\n", h->version);
message("First Offset: %lu\n", h->offset_first);
char direction[20];
if (h->forward_offset)
strcpy(direction, "Forward");
else
strcpy(direction, "Backward");
printf("Offset direction: %s\n", direction);
printf("Number masks: %lu\n", h->nber_mask);
for (size_t i = 0; i < h->nber_mask; i++) {
printf("\tMask: %s\n", h->masks_name[i]);
printf("\tValue: %lu\n", h->masks[i]);
printf("\tSize: %lu\n", h->masks_size[i]);
printf("\n");
message("Offset direction: %s\n", direction);
message("Number masks: %lu\n", h->number_mask);
for (size_t i = 0; i < h->number_mask; i++) {
message("\tMask: %s\n", h->masks[i].name);
message("\tValue: %u\n", h->masks[i].mask);
message("\tSize: %i\n", h->masks[i].size);
message("\n");
}
};
......@@ -39,34 +57,23 @@ void header_print(const struct header *h) {
*
* @param h The #header
*/
void header_free(struct header *h) {
for (size_t i = 0; i < h->nber_mask; i++) {
free(h->masks_name[i]);
}
free(h->masks_name);
free(h->masks);
free(h->masks_size);
};
void header_free(struct header *h) { free(h->masks); };
/**
* @brief check if field is present in header
* @brief Check if a field is present in the header.
*
* @param h The #header
* @param field name of the requested field
* @param ind (return value) indice of the requested field
* @param h The #header.
* @param field name of the requested field.
* @return Index of the field (-1 if not found).
*/
int header_field_is_present(const struct header *h, const char *field,
size_t *ind) {
for (size_t i = 0; i < h->nber_mask; i++) {
if (strcmp(h->masks_name[i], field) == 0) {
if (ind != NULL) {
*ind = i;
}
return 1;
int header_get_field_index(const struct header *h, const char *field) {
for (size_t i = 0; i < h->number_mask; i++) {
if (strcmp(h->masks[i].name, field) == 0) {
return i;
}
}
return 0;
return -1;
};
/**
......@@ -80,7 +87,7 @@ void header_change_offset_direction(struct header *h, void *map) {
h->forward_offset = !h->forward_offset;
size_t offset = LOGGER_VERSION_SIZE;
io_write_data(map, LOGGER_NBER_SIZE, &h->forward_offset, &offset);
io_write_data(map, LOGGER_NUMBER_SIZE, &h->forward_offset, &offset);
}
/**
......@@ -97,54 +104,49 @@ void header_read(struct header *h, void *map) {
/* read offset direction */
h->forward_offset = 0;
io_read_data(map, LOGGER_NBER_SIZE, &h->forward_offset, &offset);
io_read_data(map, LOGGER_NUMBER_SIZE, &h->forward_offset, &offset);
if (h->forward_offset != 0 && h->forward_offset != 1)
error("Non boolean value for the offset direction (%i)",
h->forward_offset);
error("Non boolean value for the offset direction (%i)", h->forward_offset);
/* read offset to first data */
h->offset_first = 0;
io_read_data(map, LOGGER_OFFSET_SIZE, &h->offset_first, &offset);
/* read name size */
h->name = 0;
io_read_data(map, LOGGER_NBER_SIZE, &h->name, &offset);
h->name_length = 0;
io_read_data(map, LOGGER_NUMBER_SIZE, &h->name_length, &offset);
/* check if value defined in this file is large enough */
if (STRING_SIZE < h->name) {
if (STRING_SIZE < h->name_length) {
error("Name too large in dump file");
}
/* read number of masks */
h->nber_mask = 0;
io_read_data(map, LOGGER_NBER_SIZE, &h->nber_mask, &offset);
h->number_mask = 0;
io_read_data(map, LOGGER_NUMBER_SIZE, &h->number_mask, &offset);
/* allocate memory */
h->masks = malloc(sizeof(size_t) * h->nber_mask);
h->masks_name = malloc(sizeof(void *) * h->nber_mask);
h->masks_size = malloc(sizeof(size_t) * h->nber_mask);
h->masks = malloc(sizeof(struct mask_data) * h->number_mask);
/* loop over all masks */
for (size_t i = 0; i < h->nber_mask; i++) {
for (size_t i = 0; i < h->number_mask; i++) {
/* read mask name */
h->masks_name[i] = malloc(h->name);
io_read_data(map, h->name, h->masks_name[i], &offset);
io_read_data(map, h->name_length, h->masks[i].name, &offset);
/* get mask value */
h->masks[i] = 1 << i;
h->masks[i].mask = 1 << i;
/* read mask data size */
h->masks_size[i] = 0;
io_read_data(map, LOGGER_NBER_SIZE, &h->masks_size[i], &offset);
h->masks[i].size = 0;
io_read_data(map, LOGGER_NUMBER_SIZE, &h->masks[i].size, &offset);
}
if (offset != h->offset_first) {
header_print(h);
error("Wrong header size (in header %li, current %li)",
h->offset_first, offset);
error("Wrong header size (in header %li, current %li)", h->offset_first,
offset);
}
};
/**
......@@ -157,9 +159,9 @@ void header_read(struct header *h, void *map) {
*/
size_t header_get_mask_size(const struct header *h, const size_t mask) {
size_t count = 0;
for (size_t i = 0; i < h->nber_mask; i++) {
if (mask & h->masks[i]) {
count += h->masks_size[i];
for (size_t i = 0; i < h->number_mask; i++) {
if (mask & h->masks[i].mask) {
count += h->masks[i].size;
}
}
return count;
......
#ifndef __LOGGER_HEADER_H__
#define __LOGGER_HEADER_H__
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* 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/>.
*
******************************************************************************/
#ifndef __LOGGER_LOGGER_HEADER_H__
#define __LOGGER_LOGGER_HEADER_H__
#include "../src/logger.h"
#include "logger_tools.h"
#include <stdio.h>
#include <stdlib.h>
#define LOGGER_VERSION_SIZE 20
#define LOGGER_NBER_SIZE 4
#define LOGGER_NUMBER_SIZE 4
#define LOGGER_OFFSET_SIZE 7
#define LOGGER_MASK_SIZE 1
......@@ -19,19 +38,13 @@ struct header {
size_t offset_first;
/* Number of bytes for names */
size_t name;
size_t name_length;
/* number of masks */
size_t nber_mask;
size_t number_mask;
/* list of masks */
size_t *masks;
/* list of mask name */
char **masks_name;
/* size of data in a mask */
size_t *masks_size;
struct mask_data *masks;
/* offset direction */
int forward_offset;
......@@ -39,10 +52,9 @@ struct header {
void header_print(const struct header *h);
void header_free(struct header *h);
int header_field_is_present(const struct header *h, const char *field,
size_t *ind);
int header_get_field_index(const struct header *h, const char *field);
void header_read(struct header *h, void *map);
size_t header_get_mask_size(const struct header *h, const size_t mask);
void header_change_offset_direction(struct header *h, void *map);
#endif // __LOGGER_HEADER_H__
#endif // __LOGGER_LOGGER_HEADER_H__
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* 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/>.
*
******************************************************************************/
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
......@@ -32,7 +50,8 @@ void io_get_file_size(int fd, size_t *size) {
void io_open_file(char *filename, int *fd, void **map) {
/* open file */
*fd = open(filename, O_RDWR);
if (*fd == -1) error("Unable to open file %s (%s)", filename, strerror(errno));
if (*fd == -1)
error("Unable to open file %s (%s)", filename, strerror(errno));
/* get file size */
size_t size = 0;
......@@ -41,7 +60,8 @@ void io_open_file(char *filename, int *fd, void **map) {
/* map memory */
*map = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, *fd, 0);
if (map == MAP_FAILED)
error("Failed to allocate map of size %zi bytes. (%s)", size, strerror(errno));
error("Failed to allocate map of size %zi bytes. (%s)", size,
strerror(errno));
}
/**
......@@ -63,58 +83,3 @@ void io_close_file(int *fd, void **map) {
close(*fd);
}
/**
* @brief read a mask with its offset
*
* @param h #header file structure
* @param map file mapping
* @param offset In: position in the file, Out: shifted by the mask + offset
* size
* @param mask mask read
* @param diff_offset offset difference to previous/next corresponding chunk
*
*/
void io_read_mask(const struct header *h, void *map, size_t *offset,
size_t *mask, size_t *diff_offset) {
/* read mask */
if (mask) {
*mask = 0;
memcpy(mask, map + *offset, LOGGER_MASK_SIZE);
}
*offset += LOGGER_MASK_SIZE;
/* read offset */
if (diff_offset) {
*diff_offset = 0;
memcpy(diff_offset, map + *offset, LOGGER_OFFSET_SIZE);
}
*offset += LOGGER_OFFSET_SIZE;
}
/**
* @brief read a single value in a file
*
* @param map file mapping
* @param size size of the chunk to read
* @param p pointer where to store the data
* @param offset In: position to read, Out: shifted by size
*/
void io_read_data(void *map, const size_t size, void *p, size_t *offset) {
memcpy(p, map + *offset, size);
*offset += size;
};
/**
* @brief write a single value in a file
*
* @param map file mapping
* @param size size of the chunk to write
* @param p pointer to the data
* @param offset In: position to write, Out: shifted by size
*
*/
void io_write_data(void *map, const size_t size, const void *p, size_t *offset) {
memcpy(map + *offset, p, size);
*offset += size;
};
#ifndef __SWIFT_LOGGER_IO_H__
#define __SWIFT_LOGGER_IO_H__
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* 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/>.
*
******************************************************************************/
#ifndef __LOGGER_LOGGER_IO_H__
#define __LOGGER_LOGGER_IO_H__
#include "logger_header.h"
#include "logger_tools.h"
......@@ -10,9 +28,63 @@
void io_get_file_size(int fd, size_t *size);
void io_open_file(char *filename, int *fd, void **map);
void io_close_file(int *fd, void **map);
void io_read_data(void *map, const size_t size, void *p, size_t *offset);
void io_write_data(void *map, const size_t size, const void *p, size_t *offset);
void io_read_mask(const struct header *h, void *map, size_t *offset,
size_t *mask, size_t *diff_offset);
#endif // __SWIFT_LOGGER_IO_H__
/**
* @brief read a mask with its offset
*
* @param h #header file structure
* @param data Pointer to the data to read.
* @param offset In: position in the file, Out: shifted by the mask + offset
* size
* @param mask mask read
* @param diff_offset offset difference to previous/next corresponding chunk
*
*/
__attribute__((always_inline)) INLINE static void io_read_mask(
const struct header *h, void *data, size_t *offset, size_t *mask,
size_t *diff_offset) {
/* read mask */
if (mask) {
*mask = 0;
memcpy(mask, data + *offset, LOGGER_MASK_SIZE);
}
*offset += LOGGER_MASK_SIZE;
/* read offset */
if (diff_offset) {
*diff_offset = 0;
memcpy(diff_offset, data + *offset, LOGGER_OFFSET_SIZE);
}
*offset += LOGGER_OFFSET_SIZE;
}
/**
* @brief read a single value in a file
*
* @param data Pointer to the data to read.
* @param size size of the chunk to read
* @param p pointer where to store the data
* @param offset In: position to read, Out: shifted by size
*/
__attribute__((always_inline)) INLINE static void io_read_data(
void *data, const size_t size, void *p, size_t *offset) {
memcpy(p, data + *offset, size);
*offset += size;
};
/**
* @brief write a single value in a file
*
* @param data Pointer to the data to read.
* @param size size of the chunk to write
* @param p pointer to the data
* @param offset In: position to write, Out: shifted by size
*
*/
__attribute__((always_inline)) INLINE static void io_write_data(
void *data, const size_t size, const void *p, size_t *offset) {
memcpy(data + *offset, p, size);
*offset += size;
};
#endif // __LOGGER_LOGGER_IO_H__
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch)
*
* 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/>.
*
******************************************************************************/
#include "logger_particle.h"
#include "logger_header.h"
#include "logger_io.h"
#include "logger_tools.h"
#include "logger_time.h"
#include "logger_tools.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/**
* @brief print a particle
* @brief Print the properties of a logger_particle.
*
* @param p #particle particle to print
* @param p The #logger_particle to print
*/
void particle_print(const struct particle *p) {
printf("ID: %lu\n", p->id);
printf("Mass: %g\n", p->mass);
printf("Time: %g\n", p->time);
printf("Cutoff Radius: %g\n", p->h);
printf("Positions: (%g, %g, %g)\n", p->pos[0], p->pos[1], p->pos[2]);
printf("Velocities: (%g, %g, %g)\n", p->vel[0], p->vel[1], p->vel[2]);
printf("Accelerations: (%g, %g, %g)\n", p->acc[0], p->acc[1], p->acc[2]);
printf("Entropy: %g\n", p->entropy);
printf("Density: %g\n", p->density);
void logger_particle_print(const struct logger_particle *p) {
message("ID: %lu\n", p->id);
message("Mass: %g\n", p->mass);
message("Time: %g\n", p->time);
message("Cutoff Radius: %g\n", p->h);
message("Positions: (%g, %g, %g)\n", p->pos[0], p->pos[1], p->pos[2]);
message("Velocities: (%g, %g, %g)\n", p->vel[0], p->vel[1], p->vel[2]);
message("Accelerations: (%g, %g, %g)\n", p->acc[0], p->acc[1], p->acc[2]);
message("Entropy: %g\n", p->entropy);
message("Density: %g\n", p->density);
}
/**
* @brief initialize a particle
* @brief Initialize a logger_particle.
*
* @param part #particle particle to initialize
* @param part The #logger_particle to initialize.
*/
void particle_init(struct particle *part) {
void logger_particle_init(struct logger_particle *part) {
for (size_t k = 0; k < DIM; k++) {
part->pos[k] = 0;
part->vel[k] = 0;
......@@ -45,18 +63,19 @@ void particle_init(struct particle *part) {
}
/**
* @brief read a single field for a particle
* @brief Read a single field for a particle
*
* @param part @particle particle to update
* @param map file mapping
* @param part The #logger_particle to update
* @param data Pointer to the data to read.
* @param offset In: read position, Out: input shifted by the required amount of
* data
* @param field field to read
* @param size number of bits to read
*
*/
void particle_read_field(struct particle *part, void *map, size_t *offset,
const char *field, const size_t size) {
void logger_particle_read_field(struct logger_particle *part, void *map,
size_t *offset, const char *field,
const size_t size) {
void *p = NULL;
if (strcmp("positions", field) == 0) {
......@@ -91,33 +110,34 @@ void particle_read_field(struct particle *part, void *map, size_t *offset,
}
/**
* @brief read a particle in the dump file
* @brief Read a particle in the dump file.
*
* @param part #particle particle to update
* @param part The #logger_particle to update.
* @param h #header structure of the file
* @param map file mapping
* @param offset offset of the chunk to read (update it to the end of the chunk)
* @param time time to interpolate (if #reader_type is an interpolating one)
* @param reader #reader_type
* @param time time to interpolate (if #logger_reader_type is an interpolating
* one)
* @param reader #logger_reader_type
* @param times #time_array times in the dump
*
*/
void particle_read(struct particle *part, const struct header *h, void *map,
size_t *offset, const double time, const int reader,
struct time_array *times) {
void logger_particle_read(struct logger_particle *part, const struct header *h,
void *map, size_t *offset, const double time,
const int reader, struct time_array *times) {
size_t mask = 0;
size_t h_offset = 0;
particle_init(part);
logger_particle_init(part);
io_read_mask(h, map, offset, &mask, &h_offset);
if (mask != 127) error("Unexpected mask: %lu", mask);
for (size_t i = 0; i < h->nber_mask; i++) {
if (mask & h->masks[i]) {
particle_read_field(part, map, offset, h->masks_name[i],
h->masks_size[i]);
for (size_t i = 0; i < h->number_mask; i++) {
if (mask & h->masks[i].mask) {
logger_particle_read_field(part, map, offset, h->masks[i].name,
h->masks[i].size);
}
}
......@@ -127,10 +147,10 @@ void particle_read(struct particle *part, const struct header *h, void *map,
part->time = -1;
/* end of const case */
if (reader == reader_const) return;
if (reader == logger_reader_const) return;
/* read next particle */
struct particle part_next;
struct logger_particle part_next;