Commit 8768ef48 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Make the copying of particles into the temporary i/o buffer a stand-alone function.

parent be5d3966
......@@ -40,8 +40,10 @@
#include "common_io.h"
/* Local includes. */
#include "engine.h"
#include "error.h"
#include "hydro.h"
#include "io_properties.h"
#include "kernel_hydro.h"
#include "part.h"
#include "units.h"
......@@ -266,7 +268,6 @@ void io_write_attribute_f(hid_t grp, const char* name, float data) {
* @param name The name of the attribute
* @param data The value to write
*/
void io_write_attribute_i(hid_t grp, const char* name, int data) {
io_write_attribute(grp, name, INT, &data, 1);
}
......@@ -401,6 +402,97 @@ void io_write_code_description(hid_t h_file) {
H5Gclose(h_grpcode);
}
/**
* @brief Copy the particle data into a temporary buffer ready for i/o.
*
* @param temp The buffer to be filled. Must be allocated and aligned properly.
* @param e The #engine.
* @param props The #io_props corresponding to the particle field we are copying.
* @param N The number of particles to copy
* @param internal_units The system of units used internally.
* @param snapshot_units The system of units used for the snapshots.
*/
void io_copy_temp_buffer(void* temp, const struct engine* e,
const struct io_props props, size_t N,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
const size_t num_elements = N * props.dimension;
const size_t dim = props.dimension;
/* Copy particle data to temporary buffer */
if (props.conversion == 0) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else { /* Converting particle to data */
if (props.convert_part_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_f(e, &parts[i], &temp_f[i * dim]);
} else if (props.convert_part_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_d(e, &parts[i], &temp_d[i * dim]);
} else if (props.convert_gpart_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_f(e, &gparts[i], &temp_f[i * dim]);
} else if (props.convert_gpart_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_d(e, &gparts[i], &temp_d[i * dim]);
} else {
error("Missing conversion function");
}
}
/* Unit conversion if necessary */
const double factor =
units_conversion_factor(internal_units, snapshot_units, props.units);
if (factor != 1.) {
/* message("Converting ! factor=%e", factor); */
if (io_is_double_precision(props.type)) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
} else {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
}
}
}
#endif /* HAVE_HDF5 */
/* ------------------------------------------------------------------------------------------------
......
......@@ -31,6 +31,10 @@
#define PARTICLE_GROUP_BUFFER_SIZE 50
#define FILENAME_BUFFER_SIZE 150
/* Avoid cyclic inclusion problems */
struct io_props;
struct engine;
#if defined(HAVE_HDF5)
/**
......@@ -72,6 +76,11 @@ void io_read_unit_system(hid_t h_file, struct unit_system* us);
void io_write_unit_system(hid_t h_grp, const struct unit_system* us,
const char* groupName);
void io_copy_temp_buffer(void* temp, const struct engine* e,
const struct io_props props, size_t N,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units);
#endif /* defined HDF5 */
void io_collect_dm_gparts(const struct gpart* const gparts, size_t Ntot,
......
......@@ -22,6 +22,9 @@
/* Config parameters. */
#include "../config.h"
/* Local includes. */
#include "inline.h"
/**
* @brief The two sorts of data present in the GADGET IC files: compulsory to
* start a run or optional.
......@@ -100,11 +103,10 @@ struct io_props {
*
* Do not call this function directly. Use the macro defined above.
*/
struct io_props io_make_input_field_(char name[FIELD_BUFFER_SIZE],
enum IO_DATA_TYPE type, int dimension,
enum DATA_IMPORTANCE importance,
enum unit_conversion_factor units,
char* field, size_t partSize) {
INLINE static struct io_props io_make_input_field_(
char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum DATA_IMPORTANCE importance, enum unit_conversion_factor units,
char* field, size_t partSize) {
struct io_props r;
strcpy(r.name, name);
r.type = type;
......@@ -143,10 +145,9 @@ struct io_props io_make_input_field_(char name[FIELD_BUFFER_SIZE],
*
* Do not call this function directly. Use the macro defined above.
*/
struct io_props io_make_output_field_(char name[FIELD_BUFFER_SIZE],
enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units,
char* field, size_t partSize) {
INLINE static struct io_props io_make_output_field_(
char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, char* field, size_t partSize) {
struct io_props r;
strcpy(r.name, name);
r.type = type;
......@@ -187,7 +188,7 @@ struct io_props io_make_output_field_(char name[FIELD_BUFFER_SIZE],
*
* Do not call this function directly. Use the macro defined above.
*/
struct io_props io_make_output_field_convert_part_FLOAT(
INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, size_t partSize,
const struct part* parts, conversion_func_part_float functionPtr) {
......@@ -224,7 +225,7 @@ struct io_props io_make_output_field_convert_part_FLOAT(
*
* Do not call this function directly. Use the macro defined above.
*/
struct io_props io_make_output_field_convert_part_DOUBLE(
INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, size_t partSize,
const struct part* parts, conversion_func_part_double functionPtr) {
......@@ -269,7 +270,7 @@ struct io_props io_make_output_field_convert_part_DOUBLE(
*
* Do not call this function directly. Use the macro defined above.
*/
struct io_props io_make_output_field_convert_gpart_FLOAT(
INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, size_t gpartSize,
const struct gpart* gparts, conversion_func_gpart_float functionPtr) {
......@@ -306,7 +307,7 @@ struct io_props io_make_output_field_convert_gpart_FLOAT(
*
* Do not call this function directly. Use the macro defined above.
*/
struct io_props io_make_output_field_convert_gpart_DOUBLE(
INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE(
char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, size_t gpartSize,
const struct gpart* gparts, conversion_func_gpart_double functionPtr) {
......
......@@ -252,9 +252,7 @@ void writeArray_chunk(struct engine* e, hid_t h_data, hid_t h_plist_id,
const struct unit_system* snapshot_units) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
const size_t num_elements = N * props.dimension;
const size_t dim = props.dimension;
/* Can't handle writes of more than 2GB */
if (N * props.dimension * typeSize > HDF5_PARALLEL_IO_MAX_BYTES)
......@@ -264,78 +262,12 @@ void writeArray_chunk(struct engine* e, hid_t h_data, hid_t h_plist_id,
/* Allocate temporary buffer */
void* temp = malloc(num_elements * typeSize);
if (temp == NULL) error("Unable to allocate memory for temporary buffer");
/* Copy particle data to temporary buffer */
if (props.conversion == 0) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else { /* Converting particle to data */
if (props.convert_part_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_f(e, &parts[i], &temp_f[i * dim]);
} else if (props.convert_part_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_d(e, &parts[i], &temp_d[i * dim]);
} else if (props.convert_gpart_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_f(e, &gparts[i], &temp_f[i * dim]);
} else if (props.convert_gpart_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
if (posix_memalign((void**)&temp, SWIFT_CACHE_ALIGNMENT,
num_elements * typeSize) != 0)
error("Unable to allocate temporary i/o buffer");
/* double conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_d(e, &gparts[i], &temp_d[i * dim]);
} else {
error("Missing conversion function");
}
}
/* Unit conversion if necessary */
const double factor =
units_conversion_factor(internal_units, snapshot_units, props.units);
if (factor != 1.) {
/* message("Converting ! factor=%e", factor); */
if (io_is_double_precision(props.type)) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
} else {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
}
}
/* Copy the particle data to the temporary buffer */
io_copy_temp_buffer(temp, e, props, N, internal_units, snapshot_units);
/* Create data space */
const hid_t h_memspace = H5Screate(H5S_SIMPLE);
......
......@@ -290,9 +290,7 @@ void writeArray(const struct engine* e, hid_t grp, char* fileName,
const struct unit_system* snapshot_units) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
const size_t num_elements = N * props.dimension;
const size_t dim = props.dimension;
/* message("Writing '%s' array...", props.name); */
......@@ -304,78 +302,11 @@ void writeArray(const struct engine* e, hid_t grp, char* fileName,
/* Allocate temporary buffer */
void* temp = NULL;
if (posix_memalign((void**)&temp, SWIFT_CACHE_ALIGNMENT,
num_elements * io_sizeof_type(props.type)) != 0)
num_elements * typeSize) != 0)
error("Unable to allocate temporary i/o buffer");
/* Copy particle data to temporary buffer */
if (props.conversion == 0) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else { /* Converting particle to data */
if (props.convert_part_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_f(e, &parts[i], &temp_f[i * dim]);
} else if (props.convert_part_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_d(e, &parts[i], &temp_d[i * dim]);
} else if (props.convert_gpart_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_f(e, &gparts[i], &temp_f[i * dim]);
} else if (props.convert_gpart_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_d(e, &gparts[i], &temp_d[i * dim]);
} else {
error("Missing conversion function");
}
}
/* Unit conversion if necessary */
const double factor =
units_conversion_factor(internal_units, snapshot_units, props.units);
if (factor != 1.) {
/* message("Converting ! factor=%e", factor); */
if (io_is_double_precision(props.type)) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
} else {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
}
}
/* Copy the particle data to the temporary buffer */
io_copy_temp_buffer(temp, e, props, N, internal_units, snapshot_units);
/* Construct information for the hyper-slab */
int rank;
......
......@@ -176,87 +176,18 @@ void writeArray(const struct engine* e, hid_t grp, char* fileName,
const struct unit_system* snapshot_units) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
const size_t num_elements = N * props.dimension;
const size_t dim = props.dimension;
/* message("Writing '%s' array...", props.name); */
/* Allocate temporary buffer */
void* temp = NULL;
if (posix_memalign((void**)&temp, SWIFT_CACHE_ALIGNMENT,
num_elements * io_sizeof_type(props.type)) != 0)
num_elements * typeSize) != 0)
error("Unable to allocate temporary i/o buffer");
/* Copy particle data to temporary buffer */
if (props.conversion == 0) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else { /* Converting particle to data */
if (props.convert_part_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_f(e, &parts[i], &temp_f[i * dim]);
} else if (props.convert_part_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct part, parts, props.parts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for parts */
for (size_t i = 0; i < N; i++)
props.convert_part_d(e, &parts[i], &temp_d[i * dim]);
} else if (props.convert_gpart_f != NULL) {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* float conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_f(e, &gparts[i], &temp_f[i * dim]);
} else if (props.convert_gpart_d != NULL) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
swift_declare_aligned_ptr(const struct gpart, gparts, props.gparts,
SWIFT_STRUCT_ALIGNMENT);
/* double conversion for gparts */
for (size_t i = 0; i < N; i++)
props.convert_gpart_d(e, &gparts[i], &temp_d[i * dim]);
} else {
error("Missing conversion function");
}
}
/* Unit conversion if necessary */
const double factor =
units_conversion_factor(internal_units, snapshot_units, props.units);
if (factor != 1.) {
/* message("Converting ! factor=%e", factor); */
if (io_is_double_precision(props.type)) {
swift_declare_aligned_ptr(double, temp_d, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= factor;
} else {
swift_declare_aligned_ptr(float, temp_f, temp, SWIFT_CACHE_ALIGNMENT);
for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= factor;
}
}
/* Copy the particle data to the temporary buffer */
io_copy_temp_buffer(temp, e, props, N, internal_units, snapshot_units);
/* Create data space */
const hid_t h_space = H5Screate(H5S_SIMPLE);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment