Commit f7fffbb9 authored by Tobias Meisel's avatar Tobias Meisel
Browse files

[MeL/IO] HDF: Add tests for multiple file output

parent 479d08b7
......@@ -43,11 +43,11 @@ static hid_t meshPropertyType2HdfType(MeshPropertyDataType const ogs_data_type)
HdfData::HdfData(void const* data_start, std::size_t const size_partitioned_dim,
std::size_t const size_tuple, std::string const& name,
MeshPropertyDataType const mesh_property_data_type,
unsigned int const num_of_files)
unsigned int const n_files)
: data_start(data_start), name(name)
{
auto const& partition_info =
getPartitionInfo(size_partitioned_dim, num_of_files);
getPartitionInfo(size_partitioned_dim, n_files);
auto const& offset_partitioned_dim = partition_info.local_offset;
offsets = {offset_partitioned_dim, 0};
......
......@@ -25,8 +25,7 @@ struct HdfData final
{
HdfData(void const* data_start, std::size_t size_partitioned_dim,
std::size_t size_tuple, std::string const& name,
MeshPropertyDataType mesh_property_data_type,
unsigned int num_of_files);
MeshPropertyDataType mesh_property_data_type, unsigned int n_files);
void const* data_start;
std::vector<Hdf5DimType> data_space;
std::vector<Hdf5DimType> offsets;
......
......@@ -214,9 +214,9 @@ HdfWriter::HdfWriter(std::vector<MeshHdfData> meshes,
std::filesystem::path const& filepath,
bool const use_compression,
bool const is_file_manager,
unsigned int const num_of_files)
unsigned int const n_files)
: _hdf5_filepath(filepath),
_file(createFile(filepath, num_of_files)),
_file(createFile(filepath, n_files)),
_meshes_group(
H5Gcreate2(_file, "/meshes", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)),
_step_times{0}, // ToDo need to be initial time
......
......@@ -43,15 +43,14 @@ public:
* @param filepath absolute or relative filepath to the hdf5 file
* @param use_compression if true gzip compression is enabled
* @param is_file_manager True if process (in parallel execution) is
* @param num_of_files Number of outputfiles
* File_Manager
* @param n_files Number of output files
*/
HdfWriter(std::vector<MeshHdfData> meshes,
unsigned long long initial_step,
std::filesystem::path const& filepath,
bool use_compression,
bool is_file_manager,
unsigned int num_of_files);
unsigned int n_files);
/**
* \brief Writes attributes. The data
* itself is hold by a structure outside of this class. The writer assumes
......
......@@ -24,7 +24,7 @@ XdmfData::XdmfData(std::size_t const size_partitioned_dim,
std::string const& name,
std::optional<MeshLib::MeshItemType> const attribute_center,
unsigned int const index,
unsigned int const num_of_files)
unsigned int const n_files)
: starts(
[&size_tuple]()
{
......@@ -54,7 +54,7 @@ XdmfData::XdmfData(std::size_t const size_partitioned_dim,
attribute_center(attribute_center),
index(index)
{
auto partition_info = getPartitionInfo(size_partitioned_dim, num_of_files);
auto partition_info = getPartitionInfo(size_partitioned_dim, n_files);
// TODO (tm) XdmfLib does not support 64 bit data types so far
assert(partition_info.local_length <
std::numeric_limits<unsigned int>::max());
......
......@@ -46,15 +46,15 @@ struct XdmfData final
* @param index The position of the DataItem parents in a grid
* (representing a single step). Convention is: 1=Time, 2=
* Geometry, 3=Topology, 4>=Attribute
* @param num_of_files If greater than 1 it groups the data of each process.
* The num_of_files specifies the number of groups
* @param n_files specifies the number of files. If greater than 1 it groups
* the data of each process to n_files
*
*/
XdmfData(std::size_t size_partitioned_dim, std::size_t size_tuple,
MeshPropertyDataType mesh_property_data_type,
std::string const& name,
std::optional<MeshLib::MeshItemType> attribute_center,
unsigned int const index, unsigned int num_of_files);
unsigned int const index, unsigned int n_files);
// a hyperslab is defined by starts and strides see
// https://www.xdmf.org/index.php/XDMF_Model_and_Format#HyperSlab
std::vector<XdmfDimType> starts;
......
......@@ -39,7 +39,7 @@ XdmfHdfWriter::XdmfHdfWriter(
std::filesystem::path const& filepath, unsigned long long const time_step,
double const initial_time,
std::set<std::string> const& variable_output_names,
bool const use_compression, unsigned int const num_of_files)
bool const use_compression, unsigned int const n_files)
{
// ogs meshes to vector of Xdmf/HDF meshes (we keep Xdmf and HDF together
// because XDMF depends on HDF) to meta
......@@ -79,12 +79,12 @@ XdmfHdfWriter::XdmfHdfWriter(
// Transform the data to be written into a format conforming with the rules
// of xdmf topology and geometry
auto const transform_ogs_mesh_data_to_xdmf_conforming_data =
[&num_of_files](auto const& mesh)
[&n_files](auto const& mesh)
{
auto flattened_geometry_values = transformToXDMFGeometry(mesh);
// actually this line is only needed to calculate the offset
XdmfHdfData const& geometry = transformGeometry(
mesh, flattened_geometry_values.data(), num_of_files);
XdmfHdfData const& geometry =
transformGeometry(mesh, flattened_geometry_values.data(), n_files);
auto const flattened_topology_values =
transformToXDMFTopology(mesh, geometry.hdf.offsets[0]);
return std::make_unique<TransformedMeshData>(
......@@ -95,7 +95,7 @@ XdmfHdfWriter::XdmfHdfWriter(
// create metadata for transformed data and original ogs mesh data
auto const transform_to_meta_data =
[&transform_ogs_mesh_data_to_xdmf_conforming_data,
&num_of_files](auto const& mesh)
&n_files](auto const& mesh)
{
// important: transformed data must survive and be unique, raw pointer
// to its memory!
......@@ -103,10 +103,10 @@ XdmfHdfWriter::XdmfHdfWriter(
transform_ogs_mesh_data_to_xdmf_conforming_data(mesh);
auto const geometry = transformGeometry(
mesh, xdmf_conforming_data->flattened_geometry_values.data(),
num_of_files);
n_files);
auto const topology = transformTopology(
xdmf_conforming_data->flattened_topology_values, num_of_files);
auto const attributes = transformAttributes(mesh, num_of_files);
xdmf_conforming_data->flattened_topology_values, n_files);
auto const attributes = transformAttributes(mesh, n_files);
return XdmfHdfMesh{std::move(geometry), std::move(topology),
std::move(attributes), mesh.get().getName(),
std::move(xdmf_conforming_data)};
......@@ -159,7 +159,7 @@ XdmfHdfWriter::XdmfHdfWriter(
auto const is_file_manager = isFileManager();
_hdf_writer = std::make_unique<HdfWriter>(std::move(hdf_meshes), time_step,
hdf_filepath, use_compression,
is_file_manager, num_of_files);
is_file_manager, n_files);
// --------------- XDMF ---------------------
// The light data is only written by just one process
......
......@@ -36,13 +36,13 @@ public:
* that change over time
* @param use_compression if true, zlib compression in HDFWriter component
* is used
* @param num_of_files number of hdf5 output files
* @param n_files number of hdf5 output files
*/
XdmfHdfWriter(
std::vector<std::reference_wrapper<const MeshLib::Mesh>> meshes,
std::filesystem::path const& filepath, unsigned long long time_step,
double initial_time, std::set<std::string> const& variable_output_names,
bool use_compression, unsigned int num_of_files);
bool use_compression, unsigned int n_files);
/**
* \brief Adds data for either lazy (xdmf) or eager (hdf) writing algorithm
......
......@@ -18,9 +18,8 @@
namespace MeshLib::IO
{
int64_t createFile(std::filesystem::path const& filepath,
unsigned int num_of_files);
int64_t createFile(std::filesystem::path const& filepath, unsigned int n_files);
int64_t openHDF5File(std::filesystem::path const& filepath,
unsigned int num_of_files);
unsigned int n_files);
int64_t createHDF5TransferPolicy();
} // namespace MeshLib::IO
......@@ -23,7 +23,7 @@ using namespace std::string_literals;
namespace MeshLib::IO
{
std::filesystem::path partitionFilename(
std::filesystem::path const& basic_filepath, int file_group)
std::filesystem::path const& basic_filepath, int const file_group)
{
std::string const filename = (file_group > 0)
? basic_filepath.stem().string() + "_"s +
......@@ -37,9 +37,9 @@ std::filesystem::path partitionFilename(
};
hid_t createFile(std::filesystem::path const& filepath,
unsigned int const num_of_files)
unsigned int const n_files)
{
auto const communicator = getCommunicator(num_of_files);
auto const communicator = getCommunicator(n_files);
MPI_Comm const comm = communicator.mpi_communicator;
MPI_Info const info = MPI_INFO_NULL;
hid_t const plist_id = H5Pcreate(H5P_FILE_ACCESS);
......@@ -55,9 +55,9 @@ hid_t createFile(std::filesystem::path const& filepath,
}
hid_t openHDF5File(std::filesystem::path const& filepath,
unsigned int const num_of_files)
unsigned int const n_files)
{
MPI_Comm const comm = getCommunicator(num_of_files).mpi_communicator;
MPI_Comm const comm = getCommunicator(n_files).mpi_communicator;
MPI_Info info = MPI_INFO_NULL;
hid_t const plist_id = H5Pcreate(H5P_FILE_ACCESS);
H5Pset_fapl_mpio(plist_id, comm, info);
......
......@@ -32,21 +32,21 @@ int getGroupIndex(int const input_index, int const input_size,
// A grouping algorithm that determines the number of groups and return the
// group idx of the specified input_index
assert(input_size >= new_group_size);
int const minimal_output_group_size =
int const minimum_output_group_size =
std::lround(input_size / new_group_size);
int const maximal_output_group_size = (input_size % new_group_size)
? minimal_output_group_size + 1
: minimal_output_group_size;
return std::lround(input_index / maximal_output_group_size);
int const maximum_output_group_size = (input_size % new_group_size)
? minimum_output_group_size + 1
: minimum_output_group_size;
return std::lround(input_index / maximum_output_group_size);
};
FileCommunicator getCommunicator(unsigned int const num_of_files)
FileCommunicator getCommunicator(unsigned int const n_files)
{
int num_procs;
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
int rank_id;
MPI_Comm_rank(MPI_COMM_WORLD, &rank_id);
int file_group_id = getGroupIndex(rank_id, num_procs, num_of_files);
int const file_group_id = getGroupIndex(rank_id, num_procs, n_files);
MPI_Comm new_communicator;
MPI_Comm_split(MPI_COMM_WORLD, file_group_id, rank_id, &new_communicator);
return FileCommunicator{std::move(new_communicator),
......
/**
* \file
* \author Tobias Meisel
* \date 2021-09-14
* \brief Assigns to each MPI communicator an output file name by attribute
* color There are multiple implementation to this interface!
* \copyright
* Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include <mpi.h>
......@@ -12,5 +26,5 @@ struct FileCommunicator final
int color;
std::filesystem::path output_filename;
};
FileCommunicator getCommunicator(unsigned int num_of_files);
FileCommunicator getCommunicator(unsigned int n_files);
} // namespace MeshLib::IO
\ No newline at end of file
......@@ -31,9 +31,9 @@ bool isFileManager()
}
PartitionInfo getPartitionInfo(std::size_t const size,
unsigned int const num_of_files)
unsigned int const n_files)
{
MPI_Comm const mpi_comm = getCommunicator(num_of_files).mpi_communicator;
MPI_Comm const mpi_comm = getCommunicator(n_files).mpi_communicator;
int mpi_size;
int mpi_rank;
MPI_Comm_size(mpi_comm, &mpi_size);
......
......@@ -25,6 +25,6 @@ struct PartitionInfo
};
PartitionInfo getPartitionInfo(std::size_t const size,
unsigned int const num_of_files);
unsigned int const n_files);
bool isFileManager();
} // namespace MeshLib::IO
......@@ -71,7 +71,7 @@ constexpr auto cellTypeOGS2XDMF(MeshLib::CellType const& cell_type)
std::optional<XdmfHdfData> transformAttribute(
std::pair<std::string, PropertyVectorBase*> const& property_pair,
unsigned int const num_of_files)
unsigned int const n_files)
{
// 3 data that will be captured and written by lambda f below
MeshPropertyDataType data_type = MeshPropertyDataType::unknown;
......@@ -192,17 +192,17 @@ std::optional<XdmfHdfData> transformAttribute(
std::string const& name = property_base->getPropertyName();
HdfData hdf = {data_ptr, num_of_tuples, ui_global_components,
name, data_type, num_of_files};
name, data_type, n_files};
XdmfData xdmf = {num_of_tuples, ui_global_components, data_type,
name, mesh_item_type, 0,
num_of_files};
n_files};
return XdmfHdfData{std::move(hdf), std::move(xdmf)};
}
std::vector<XdmfHdfData> transformAttributes(MeshLib::Mesh const& mesh,
unsigned int const num_of_files)
unsigned int const n_files)
{
MeshLib::Properties const& properties = mesh.getProperties();
......@@ -216,8 +216,8 @@ std::vector<XdmfHdfData> transformAttributes(MeshLib::Mesh const& mesh,
continue;
}
if (auto const attribute = transformAttribute(
std::pair(name, property_base), num_of_files))
if (auto const attribute =
transformAttribute(std::pair(name, property_base), n_files))
{
attributes.push_back(attribute.value());
}
......@@ -247,7 +247,7 @@ std::vector<double> transformToXDMFGeometry(MeshLib::Mesh const& mesh)
XdmfHdfData transformGeometry(MeshLib::Mesh const& mesh,
double const* data_ptr,
unsigned int const num_of_files)
unsigned int const n_files)
{
std::string const name = "geometry";
std::vector<MeshLib::Node*> const& nodes = mesh.getNodes();
......@@ -260,11 +260,11 @@ XdmfHdfData transformGeometry(MeshLib::Mesh const& mesh,
point_size,
name,
MeshPropertyDataType::float64,
num_of_files};
n_files};
XdmfData const xdmf = {
partition_dim, point_size, MeshPropertyDataType::float64,
name, std::nullopt, 2,
num_of_files};
n_files};
return XdmfHdfData{std::move(hdf), std::move(xdmf)};
}
......@@ -297,15 +297,15 @@ std::vector<int> transformToXDMFTopology(MeshLib::Mesh const& mesh,
}
XdmfHdfData transformTopology(std::vector<int> const& values,
unsigned int const num_of_files)
unsigned int const n_files)
{
std::string const name = "topology";
HdfData const hdf = {
values.data(), values.size(), 1, name, MeshPropertyDataType::int32,
num_of_files};
n_files};
XdmfData const xdmf = {
values.size(), 1, MeshPropertyDataType::int32, name, std::nullopt, 3,
num_of_files};
n_files};
return XdmfHdfData{std::move(hdf), std::move(xdmf)};
}
......
......@@ -26,31 +26,31 @@ namespace MeshLib::IO
/**
* \brief Create meta data for attributes used for hdf5 and xdmf
* @param mesh OGS mesh can be mesh or partitionedMesh
* @param num_of_files If greater than 1 it groups the data of each process. The
* num_of_files specifies the number of groups
* @param n_files specifies the number of files. If greater than 1 it groups the
* data of each process to n_files
* @return vector of meta data
*/
std::vector<XdmfHdfData> transformAttributes(MeshLib::Mesh const& mesh,
unsigned int num_of_files);
unsigned int n_files);
/**
* \brief Create meta data for geometry used for hdf5 and xdmf
* @param mesh OGS mesh can be mesh or partitionedMesh
* @param data_ptr Memory location of geometry values.
* @param num_of_files If greater than 1 it groups the data of each process. The
* num_of_files specifies the number of groups
* @param n_files specifies the number of files. If greater than 1 it groups the
* data of each process to n_files
* @return Geometry meta data
*/
XdmfHdfData transformGeometry(MeshLib::Mesh const& mesh, double const* data_ptr,
unsigned int num_of_files);
unsigned int n_files);
/**
* \brief Create meta data for topology used for HDF5 and XDMF
* @param values actual topology values to get size and memory location
* @param num_of_files If greater than 1 it groups the data of each process. The
* num_of_files specifies the number of groups
* @param n_files specifies the number of files. If greater than 1 it groups the
* data of each process to n_files
* @return Topology meta data
*/
XdmfHdfData transformTopology(std::vector<int> const& values,
unsigned int num_of_files);
unsigned int n_files);
/**
* \brief Copies all node points into a new vector. Contiguous data used for
* writing. Conform with XDMF standard in
......
......@@ -95,7 +95,7 @@ bool Output::shallDoOutput(int timestep, double const t)
Output::Output(std::string directory, OutputType file_type,
std::string file_prefix, std::string file_suffix,
bool const compress_output, unsigned int const num_of_files,
bool const compress_output, unsigned int const n_files,
std::string const& data_mode,
bool const output_nonlinear_iteration_results,
std::vector<PairRepeatEachSteps> repeats_each_steps,
......@@ -108,7 +108,7 @@ Output::Output(std::string directory, OutputType file_type,
_output_file_prefix(std::move(file_prefix)),
_output_file_suffix(std::move(file_suffix)),
_output_file_compression(compress_output),
_num_of_files(num_of_files),
_n_files(n_files),
_output_file_data_mode(convertVtkDataMode(data_mode)),
_output_nonlinear_iteration_results(output_nonlinear_iteration_results),
_repeats_each_steps(std::move(repeats_each_steps)),
......@@ -183,7 +183,7 @@ struct Output::OutputFile
int const iteration, int const data_mode_,
bool const compression_,
std::set<std::string> const& outputnames,
unsigned int const num_of_files)
unsigned int const n_files)
: name(constructFilename(type, prefix, suffix, mesh_name, timestep, t,
iteration)),
path(BaseLib::joinPaths(directory, name)),
......@@ -191,7 +191,7 @@ struct Output::OutputFile
data_mode(data_mode_),
compression(compression_),
outputnames(outputnames),
num_of_files(num_of_files)
n_files(n_files)
{
}
......@@ -206,7 +206,7 @@ struct Output::OutputFile
//! Enables or disables zlib-compression of the output files.
bool const compression;
std::set<std::string> outputnames;
unsigned int num_of_files;
unsigned int n_files;
static std::string constructFilename(OutputType const type,
std::string prefix, std::string suffix,
std::string mesh_name,
......@@ -250,7 +250,7 @@ void Output::outputMeshXdmf(
_mesh_xdmf_hdf_writer = std::make_unique<MeshLib::IO::XdmfHdfWriter>(
std::move(meshes), path, timestep, t,
_output_data_specification.output_variables,
output_file.compression, output_file.num_of_files);
output_file.compression, output_file.n_files);
}
else
{
......@@ -337,7 +337,7 @@ void Output::doOutputAlways(Process const& process,
_output_directory, _output_file_type, _output_file_prefix, "",
name, timestep, t, iteration, _output_file_data_mode,
_output_file_compression,
_output_data_specification.output_variables, _num_of_files);
_output_data_specification.output_variables, _n_files);
outputMeshXdmf(std::move(file), std::move(meshes), timestep, t);
}
......
......@@ -39,8 +39,8 @@ public:
public:
Output(std::string directory, OutputType const type, std::string prefix,
std::string suffix, bool const compress_output,
unsigned int num_of_files, std::string const& data_mode,
std::string suffix, bool const compress_output, unsigned int n_files,
std::string const& data_mode,
bool const output_nonlinear_iteration_results,
std::vector<PairRepeatEachSteps> repeats_each_steps,
std::vector<double>&& fixed_output_times,
......@@ -109,7 +109,7 @@ private:
//! Enables or disables zlib-compression of the output files.
bool const _output_file_compression;
//! Specifies the number of hdf5 output files.
unsigned int const _num_of_files;
unsigned int const _n_files;
//! Chooses vtk's data mode for output following the enumeration given in
/// the vtkXMLWriter: {Ascii, Binary, Appended}. See vtkXMLWriter
......
......@@ -416,7 +416,7 @@ AddTest(
)
AddTest(
NAME ParallelFEM_GroundWaterFlow3D_NeumannBC_XDMF_np3
NAME ParallelFEM_GroundWaterFlow3D_NeumannBC_XDMF_np3_1file
PATH EllipticPETSc
EXECUTABLE ogs
EXECUTABLE_ARGS cube_1e3_XDMF_np3.prj
......@@ -431,9 +431,9 @@ AddTest(
AddTest(
NAME ParallelFEM_GroundWaterFlow3D_NeumannBC_XDMF_np3_2files
PATH EllipticPETSc
PATH EllipticPETSc/XDMF_NP3_2
EXECUTABLE ogs
EXECUTABLE_ARGS cube_1e3_XDMF_np3_2files.prj
EXECUTABLE_ARGS ../cube_1e3_XDMF_np3_2files.prj
WRAPPER mpirun
WRAPPER_ARGS -np 3
TESTER xdmfdiff
......@@ -445,9 +445,9 @@ AddTest(
AddTest(
NAME ParallelFEM_GroundWaterFlow3D_NeumannBC_XDMF_np3_3files
PATH EllipticPETSc
PATH EllipticPETSc/XDMF_NP3_3
EXECUTABLE ogs
EXECUTABLE_ARGS cube_1e3_XDMF_np3_3files.prj
EXECUTABLE_ARGS ../cube_1e3_XDMF_np3_3files.prj
WRAPPER mpirun
WRAPPER_ARGS -np 3
TESTER xdmfdiff
......
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