diff --git a/src/csds_loader_io.h b/src/csds_loader_io.h index ca7ae26b93a29442dca3a95ccb55db619abbfb1c..91b60bc44584b788bfc41c0fd5e608dc3ad81400 100644 --- a/src/csds_loader_io.h +++ b/src/csds_loader_io.h @@ -51,6 +51,7 @@ void csds_loader_io_munmap_file(struct mapped_file *map); /** * @brief read a mask with its offset. * + * @param h #header file structure. * @param data Pointer to the data to read. * @param mask (output) mask read from the data. * @param diff_offset (output) offset difference to previous/next corresponding @@ -59,7 +60,7 @@ void csds_loader_io_munmap_file(struct mapped_file *map); * @return memory after the record header. */ __attribute__((always_inline)) INLINE static char *csds_loader_io_read_mask( - char *data, mask_type *mask, size_t *diff_offset) { + const struct header *h, char *data, mask_type *mask, size_t *diff_offset) { /* read mask */ if (mask) { *mask = 0; diff --git a/src/csds_particle.c b/src/csds_particle.c index a23b831264649463cd011f6f9c89410ba678fa6e..70e62d4a23045c681a8fde6b30bd66ea3f1c9aec 100644 --- a/src/csds_particle.c +++ b/src/csds_particle.c @@ -29,6 +29,83 @@ #include <stdio.h> #include <stdlib.h> +/** + * @brief Read a particle (of any type) record in the log file. + * + * @param reader The #csds_reader. + * @param offset offset of the record to read. + * @param output Buffer for the requested field. + * @param part_type The particle type. + * @param field_read The field to read. + * @param derivative The derivative to read (0 for the field). + * @param mask (out) The mask of the record. + * @param h_offset (out) Difference of offset with the next record. + * + * @return position after the record. + */ +__attribute__((always_inline)) INLINE size_t csds_particle_read_field( + const struct csds_reader *reader, size_t offset, void *output, + const enum part_type part_type, const struct field_information *field_read, + const int derivative, mask_type *mask, size_t *h_offset) { + + /* Get a few pointers. */ + const struct header *h = &reader->log.header; + const struct field_information *fields = h->fields[part_type]; + char *map = reader->log.log.map; + + *mask = 0; + *h_offset = 0; + + /* Read the record's mask. */ + map = csds_loader_io_read_mask(h, map + offset, mask, h_offset); + + /* Check if it is not a time record. */ + if (*mask == TIMESTAMP_MASK) { + error_python("Cannot read a particle from timestep record."); + } + +#ifdef SWIFT_DEBUG_CHECKS + if (derivative == 1 && field_read->first.field == field_enum_none) { + error("Trying to read the non existing first derivative."); + } + if (derivative == 2 && field_read->second.field == field_enum_none) { + error("Trying to read the non existing second derivative."); + } +#endif + + /* Get the position of the field to read */ + const int position = derivative == 0 + ? field_read->field.position + : derivative == 1 ? field_read->first.position + : field_read->second.position; + +#ifdef SWIFT_DEBUG_CHECKS + if (position < 0) { + error("Position not set (derivative %i of %s)", derivative, + field_enum_get_name(field_read->field.field)); + } +#endif + + /* Read the record and copy it to a particle. */ + for (int i = 0; i < h->number_fields[part_type]; i++) { + + /* Is the mask present? */ + if (!(*mask & fields[i].field.mask)) { + continue; + } + + if (position == i) { + /* Read the data. */ + map = csds_loader_io_read_data(map, fields[i].field.size, output); + } else { + /* Update the buffer's position. */ + map += fields[i].field.size; + } + } + + return map - reader->log.log.map; +} + /** * @brief Read the special flag of a particle (of any type) in the log file. * @@ -47,13 +124,14 @@ csds_particle_read_special_flag(const struct csds_reader *reader, size_t offset, int *part_type) { /* Get a few pointers. */ + const struct header *h = &reader->log.header; char *map = reader->log.log.map; *mask = 0; *h_offset = 0; /* Read the record's mask. */ - map = csds_loader_io_read_mask(map + offset, mask, h_offset); + map = csds_loader_io_read_mask(h, map + offset, mask, h_offset); /* Check if it is not a time record. */ if (*mask == TIMESTAMP_MASK) { diff --git a/src/csds_particle.h b/src/csds_particle.h index 505e42076c40409553573a3e100b62781856e1f8..67fbad442ee005073bc11024b69aacb02c06959b 100644 --- a/src/csds_particle.h +++ b/src/csds_particle.h @@ -24,7 +24,6 @@ /* Include the other local files. */ #include "csds_header.h" -#include "csds_loader_io.h" #include "csds_parameters.h" #include "csds_time.h" @@ -39,6 +38,12 @@ enum csds_reader_type { csds_reader_lin, /* Linear interpolation. */ }; +size_t csds_particle_read_field(const struct csds_reader *reader, size_t offset, + void *output, const enum part_type part_type, + const struct field_information *field, + const int derivative, mask_type *mask, + size_t *h_offset); + void csds_particle_interpolate_field( const double t_before, const struct csds_reader_field *restrict before, const double t_after, const struct csds_reader_field *restrict after, @@ -50,80 +55,6 @@ enum csds_special_flags csds_particle_read_special_flag( const struct csds_reader *reader, size_t offset, mask_type *mask, size_t *h_offset, int *data, int *part_type); -/** - * @brief Read a particle (of any type) record in the log file. - * - * @param reader The #csds_reader. - * @param offset offset of the record to read. - * @param output Buffer for the requested field. - * @param part_type The particle type. - * @param field_read The field to read. - * @param derivative The derivative to read (0 for the field). - * @param mask (out) The mask of the record. - * @param h_offset (out) Difference of offset with the next record. - * - * @return position after the record. - */ -__attribute__((always_inline)) INLINE static size_t csds_particle_read_field( - size_t offset, void *output, const struct field_information *field_read, - const int derivative, mask_type *mask, size_t *h_offset, - const struct field_information *fields, int number_fields, char *log_map) { - - char *map = log_map; - - *mask = 0; - *h_offset = 0; - - /* Read the record's mask. */ - map = csds_loader_io_read_mask(map + offset, mask, h_offset); - - /* Check if it is not a time record. */ - if (*mask == TIMESTAMP_MASK) { - error_python("Cannot read a particle from timestep record."); - } - -#ifdef SWIFT_DEBUG_CHECKS - if (derivative == 1 && field_read->first.field == field_enum_none) { - error("Trying to read the non existing first derivative."); - } - if (derivative == 2 && field_read->second.field == field_enum_none) { - error("Trying to read the non existing second derivative."); - } -#endif - - /* Get the position of the field to read */ - const int position = derivative == 0 - ? field_read->field.position - : derivative == 1 ? field_read->first.position - : field_read->second.position; - -#ifdef SWIFT_DEBUG_CHECKS - if (position < 0) { - error("Position not set (derivative %i of %s)", derivative, - field_enum_get_name(field_read->field.field)); - } -#endif - - /* Read the record and copy it to a particle. */ - for (int i = 0; i < number_fields; i++) { - - /* Is the mask present? */ - if (!(*mask & fields[i].field.mask)) { - continue; - } - - if (position == i) { - /* Read the data. */ - map = csds_loader_io_read_data(map, fields[i].field.size, output); - } else { - /* Update the buffer's position. */ - map += fields[i].field.size; - } - } - - return map - log_map; -} - /** * @brief Extract the flag and its related data from the data inside a record. * diff --git a/src/csds_reader.c b/src/csds_reader.c index b09e9d7309603722d6c17ddf277d21fe9463ccbf..03546871d0645fa17ce1c63f6768d265ec3d66cf 100644 --- a/src/csds_reader.c +++ b/src/csds_reader.c @@ -424,7 +424,7 @@ int csds_reader_read_field(struct csds_reader *reader, double time, */ while (offset < offset_time) { /* Read the particle. */ - csds_loader_io_read_mask(reader->log.log.map + offset, &mask, &h_offset); + csds_loader_io_read_mask(h, reader->log.log.map + offset, &mask, &h_offset); /* Is the particle removed from the logfile? */ if (mask & SPECIAL_FLAGS_MASK) { @@ -460,10 +460,8 @@ int csds_reader_read_field(struct csds_reader *reader, double time, } /* Read the field */ - csds_particle_read_field(offset_before, output, field_wanted, - /* derivative */ 0, &mask, &h_offset, - h->fields[type], h->number_fields[type], - reader->log.log.map); + csds_particle_read_field(reader, offset_before, output, type, field_wanted, + /* derivative */ 0, &mask, &h_offset); /* Deal with the first derivative. */ int first_found = field_wanted->first.field != field_enum_none && @@ -472,10 +470,9 @@ int csds_reader_read_field(struct csds_reader *reader, double time, if (first_found) { /* Read the first derivative */ - csds_particle_read_field(offset_before, first_deriv, field_wanted, - /* derivative */ 1, &mask, &h_offset, - h->fields[type], h->number_fields[type], - reader->log.log.map); + csds_particle_read_field(reader, offset_before, first_deriv, type, + field_wanted, /* derivative */ 1, &mask, + &h_offset); } /* Deal with the second derivative. */ @@ -486,10 +483,9 @@ int csds_reader_read_field(struct csds_reader *reader, double time, if (second_found) { /* Read the first derivative */ - csds_particle_read_field(offset_before, second_deriv, field_wanted, - /* derivative */ 2, &mask, &h_offset, - h->fields[type], h->number_fields[type], - reader->log.log.map); + csds_particle_read_field(reader, offset_before, second_deriv, type, + field_wanted, /* derivative */ 2, &mask, + &h_offset); } /* Get the time. */ @@ -505,7 +501,8 @@ int csds_reader_read_field(struct csds_reader *reader, double time, while (1) { /* Read the particle. */ - csds_loader_io_read_mask(reader->log.log.map + offset, &mask, &h_offset); + csds_loader_io_read_mask(h, reader->log.log.map + offset, &mask, + &h_offset); /* Do we have the field? */ if (mask & field_wanted->field.mask) { @@ -525,10 +522,8 @@ int csds_reader_read_field(struct csds_reader *reader, double time, char output_after[field_wanted->field.size]; /* Read the field */ - csds_particle_read_field(offset, output_after, field_wanted, - /* derivative */ 0, &mask, &h_offset, - h->fields[type], h->number_fields[type], - reader->log.log.map); + csds_particle_read_field(reader, offset, output_after, type, field_wanted, + /* derivative */ 0, &mask, &h_offset); /* Deal with the first derivative. */ char first_deriv_after[field_wanted->first.size]; @@ -538,10 +533,9 @@ int csds_reader_read_field(struct csds_reader *reader, double time, mask & field_wanted->first.mask; if (first_found) { /* Read the first derivative */ - csds_particle_read_field(offset, first_deriv_after, field_wanted, - /*derivative*/ 1, &mask, &h_offset, - h->fields[type], h->number_fields[type], - reader->log.log.map); + csds_particle_read_field(reader, offset, first_deriv_after, type, + field_wanted, /*derivative*/ 1, &mask, + &h_offset); } /* Deal with the second derivative. */ @@ -552,10 +546,9 @@ int csds_reader_read_field(struct csds_reader *reader, double time, second_found && mask & field_wanted->second.mask; if (second_found) { /* Read the second derivative */ - csds_particle_read_field(offset, second_deriv_after, field_wanted, - /* derivative */ 2, &mask, &h_offset, - h->fields[type], h->number_fields[type], - reader->log.log.map); + csds_particle_read_field(reader, offset, second_deriv_after, type, + field_wanted, /* derivative */ 2, &mask, + &h_offset); } /* Get the time. */ @@ -1092,7 +1085,7 @@ size_t csds_reader_read_record(struct csds_reader *reader, void **output, size_t h_offset = 0; /* Read the record's mask. */ - map = csds_loader_io_read_mask(map + offset, &mask, &h_offset); + map = csds_loader_io_read_mask(h, map + offset, &mask, &h_offset); *is_particle = !(mask & TIMESTAMP_MASK); /* The record is a particle. */ @@ -1100,9 +1093,8 @@ size_t csds_reader_read_record(struct csds_reader *reader, void **output, size_t offset_tmp = offset; for (int i = 0; i < h->number_fields[swift_type_gas]; i++) { offset = csds_particle_read_field( - offset_tmp, output[i], &h->fields[swift_type_gas][i], - /* derivative */ 0, &mask, &h_offset, h->fields[swift_type_gas], - h->number_fields[swift_type_gas], reader->log.log.map); + reader, offset_tmp, output[i], swift_type_gas, + &h->fields[swift_type_gas][i], /* derivative */ 0, &mask, &h_offset); } } /* The record is a timestamp. */ diff --git a/src/csds_reader_generate_index.c b/src/csds_reader_generate_index.c index b820dba3e32c2e96dde56b2a9299c9de31566993..eff5397b91efbb8efee0413a0d9be3d9290e73ce 100644 --- a/src/csds_reader_generate_index.c +++ b/src/csds_reader_generate_index.c @@ -317,7 +317,7 @@ size_t csds_reader_get_initial_state(const struct csds_reader *reader, /* Skip the time record */ mask_type time_mask = 0; - csds_loader_io_read_mask(log->log.map + offset_first, &time_mask, NULL); + csds_loader_io_read_mask(h, log->log.map + offset_first, &time_mask, NULL); const int time_size = header_get_record_size_from_mask(h, time_mask); offset_first += time_size + size_record_header; @@ -352,10 +352,8 @@ size_t csds_reader_get_initial_state(const struct csds_reader *reader, /* Read the particle ID */ int64_t id = 0; - csds_particle_read_field(offset, &id, field_id, - /* derivative */ 0, &mask, &prev_offset, - h->fields[part_type], h->number_fields[part_type], - reader->log.log.map); + csds_particle_read_field(reader, offset, &id, part_type, field_id, + /* derivative */ 0, &mask, &prev_offset); /* Log the particle */ struct index_data item = {id, offset}; @@ -425,6 +423,7 @@ void csds_reader_update_particles_to_next_index_mapper(void *map_data, struct update_particle_data *data = (struct update_particle_data *)extra_data; const struct csds_reader *reader = data->reader; const struct csds_logfile *log = &reader->log; + const struct header *h = &log->header; struct csds_hashmap *current_state = data->current_state; /* Loop over the particles */ @@ -443,7 +442,7 @@ void csds_reader_update_particles_to_next_index_mapper(void *map_data, /* Get the full mask */ mask_type full_mask = 0; size_t h_offset = 0; - csds_loader_io_read_mask(log->log.map + current_offset, &full_mask, + csds_loader_io_read_mask(h, log->log.map + current_offset, &full_mask, &h_offset); /* Ensures that a special flag is present in the mask */ @@ -459,7 +458,8 @@ void csds_reader_update_particles_to_next_index_mapper(void *map_data, /* Get the mask */ mask_type mask = 0; h_offset = 0; - csds_loader_io_read_mask(log->log.map + current_offset, &mask, &h_offset); + csds_loader_io_read_mask(h, log->log.map + current_offset, &mask, + &h_offset); /* update the offset */ current_offset += h_offset; @@ -579,7 +579,7 @@ size_t csds_reader_update_state_to_next_index( int data = 0; /* Get the mask */ - csds_loader_io_read_mask(log->log.map + offset, &mask, &h_offset); + csds_loader_io_read_mask(h, log->log.map + offset, &mask, &h_offset); /* Go to the next record */ const size_t old_offset = offset; @@ -613,10 +613,8 @@ size_t csds_reader_update_state_to_next_index( /* Read the ID */ int64_t id = 0; - csds_particle_read_field(old_offset, &id, field_id, - /* derivative */ 0, &mask, &h_offset, - h->fields[part_type], h->number_fields[part_type], - reader->log.log.map); + csds_particle_read_field(reader, old_offset, &id, part_type, field_id, + /* derivative */ 0, &mask, &h_offset); /* Add the particle to the arrays */ if (flag == csds_flag_change_type || flag == csds_flag_mpi_exit || diff --git a/src/csds_time.c b/src/csds_time.c index 7875af497c0cc190add18cd7d60745d8575a81f3..8e73367d773edc07d7e47d024c8e5da5c2856a91 100644 --- a/src/csds_time.c +++ b/src/csds_time.c @@ -95,7 +95,7 @@ size_t time_read(struct time_record *time_record, time_record->time = 0; /* read record header. */ - map = csds_loader_io_read_mask(map + offset, &mask, &prev_offset); + map = csds_loader_io_read_mask(h, map + offset, &mask, &prev_offset); /* check if reading a time record. */ if (TIMESTAMP_MASK != mask) error_python("Not a time record."); @@ -122,7 +122,7 @@ size_t time_offset_first_record(const struct header *h) { char *map = h->log->log.map; mask_type mask = 0; - csds_loader_io_read_mask(map + offset, &mask, NULL); + csds_loader_io_read_mask(h, map + offset, &mask, NULL); if (mask != TIMESTAMP_MASK) error_python("Log file should begin by timestep."); diff --git a/src/csds_tools.c b/src/csds_tools.c index a1f796d92c9e553abe006613aa46082c6875dd06..efdfd1a2732cc1753f466695df5a015a07a9f537 100644 --- a/src/csds_tools.c +++ b/src/csds_tools.c @@ -60,7 +60,7 @@ int _tools_get_next_record_forward(const struct header *h, char *map, size_t diff_offset = 0; /* Read the offset. */ - map = csds_loader_io_read_mask(map + *offset, NULL, &diff_offset); + map = csds_loader_io_read_mask(h, map + *offset, NULL, &diff_offset); if (diff_offset == 0) return -1; @@ -91,7 +91,7 @@ int _tools_get_next_record_backward(const struct header *h, char *map, while (current_offset < file_size) { mask_type mask = 0; size_t prev_offset; - csds_loader_io_read_mask(map + current_offset, &mask, &prev_offset); + csds_loader_io_read_mask(h, map + current_offset, &mask, &prev_offset); prev_offset = current_offset - prev_offset - record_header; if (*offset == prev_offset) { @@ -123,7 +123,7 @@ size_t tools_reverse_offset(const struct header *h, char *file_map, char *map = file_map; /* read mask + offset. */ - map = csds_loader_io_read_mask(map + offset, &mask, &prev_offset); + map = csds_loader_io_read_mask(h, map + offset, &mask, &prev_offset); /* write offset of zero (in case it is the last record). */ const size_t zero = 0; @@ -147,7 +147,7 @@ size_t tools_reverse_offset(const struct header *h, char *file_map, #ifdef SWIFT_DEBUG_CHECKS mask_type prev_mask = 0; map = map - CSDS_MASK_SIZE - CSDS_OFFSET_SIZE; - csds_loader_io_read_mask(map, &prev_mask, NULL); + csds_loader_io_read_mask(h, map, &prev_mask, NULL); /* Check if we are not mixing timestamp and particles */ if ((prev_mask != TIMESTAMP_MASK && mask == TIMESTAMP_MASK) || @@ -184,7 +184,7 @@ size_t tools_check_record_consistency(const struct csds_reader *reader, size_t pointed_offset; /* read mask + offset. */ - map = csds_loader_io_read_mask(map, &mask, &pointed_offset); + map = csds_loader_io_read_mask(h, map, &mask, &pointed_offset); /* set offset after current record. */ map = map + header_get_record_size_from_mask(h, mask); @@ -211,7 +211,7 @@ size_t tools_check_record_consistency(const struct csds_reader *reader, /* read mask of the pointed record. */ mask_type pointed_mask = 0; - csds_loader_io_read_mask(file_init + pointed_offset, &pointed_mask, NULL); + csds_loader_io_read_mask(h, file_init + pointed_offset, &pointed_mask, NULL); /* check if not mixing timestamp and particles. */ if ((pointed_mask != TIMESTAMP_MASK && mask == TIMESTAMP_MASK) ||