DNDSR 0.2.1
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
SerializerFactory.hpp
Go to the documentation of this file.
1#pragma once
2/// @file SerializerFactory.hpp
3/// @brief Configurable factory that builds either a @ref DNDS::SerializerJSON "SerializerJSON" or a
4/// @ref DNDS::SerializerH5 "SerializerH5" with all tunables exposed through the DNDS config system.
5
6#include "SerializerBase.hpp"
7#include "SerializerJSON.hpp"
8#include "SerializerH5.hpp"
9#include "JsonUtil.hpp"
11
12#include <utility>
13
14namespace DNDS::Serializer
15{
16 /**
17 * @brief Config-backed factory selecting between JSON and HDF5 serializers.
18 *
19 * @details Exposes the tunables of both backends under a single config
20 * schema so users can switch formats by changing one JSON field. See
21 * @ref DNDS_DECLARE_CONFIG body for the full list of fields.
22 */
24 {
25 /// @brief Backend selector: `"JSON"` or `"H5"`.
26 std::string type = "JSON";
27 /// @brief HDF5 gzip deflate level (0 = off, 9 = max).
29 /// @brief HDF5 chunk size (0 = library-chosen auto).
30 int hdfChunkSize = 0;
31 /// @brief Use collective HDF5 I/O for data arrays.
32 bool hdfCollOnData = false;
33 /// @brief Use collective HDF5 I/O for metadata (usually safe).
34 bool hdfCollOnMeta = true;
35 /// @brief Compression level used by the JSON backend's binary codec.
37 /// @brief Whether to apply the byte-codec to uint8 arrays in JSON (faster writes).
39
40 SerializerFactory() = default;
41 /// @brief Construct with a specific backend name; other fields stay at defaults.
42 SerializerFactory(std::string _type) : type(std::move(_type)) {}
43
45 {
46 // clang-format off
47 DNDS_FIELD(type, "Serializer backend: \"JSON\" or \"H5\"",
48 DNDS::Config::enum_values({"JSON", "H5"}));
49 DNDS_FIELD(hdfDeflateLevel, "HDF5 deflate compression level",
51 DNDS_FIELD(hdfChunkSize, "HDF5 chunk size (0=auto)",
53 DNDS_FIELD(hdfCollOnData, "HDF5 collective I/O on data arrays");
54 DNDS_FIELD(hdfCollOnMeta, "HDF5 collective I/O on metadata");
55 DNDS_FIELD(jsonBinaryDeflateLevel, "JSON binary deflate level",
57 DNDS_FIELD(jsonUseCodecOnUInt8, "Apply codec on uint8 arrays in JSON");
58 // clang-format on
59 }
60
61 /// @brief Instantiate the selected serializer and apply its tunables.
62 /// @param mpi MPI context (used only by the H5 backend).
63 [[nodiscard]] SerializerBaseSSP BuildSerializer(const MPIInfo &mpi) const
64 {
65 SerializerBaseSSP serializerP;
66 if (type == "JSON")
67 {
68 serializerP = std::make_shared<SerializerJSON>();
69 std::dynamic_pointer_cast<SerializerJSON>(serializerP)->SetUseCodecOnUint8(jsonUseCodecOnUInt8);
70 std::dynamic_pointer_cast<SerializerJSON>(serializerP)->SetDeflateLevel(jsonBinaryDeflateLevel);
71 }
72 else if (type == "H5")
73 {
74 serializerP = std::make_shared<SerializerH5>(mpi);
75 std::dynamic_pointer_cast<SerializerH5>(serializerP)->SetChunkAndDeflate(hdfChunkSize, hdfDeflateLevel);
76 std::dynamic_pointer_cast<SerializerH5>(serializerP)->SetCollectiveRW(hdfCollOnMeta, hdfCollOnData);
77 }
78 else
79 DNDS_assert_info(false, "type of serializer not existent: " + type);
80 return serializerP;
81 }
82
83 /**
84 * @brief Expand a user-supplied base file name into the backend-specific path layout.
85 *
86 * @details JSON uses one file per rank under a `<name>.dir/` directory
87 * (`<rank>.json`); H5 produces a single `<name>.dnds.h5` file.
88 *
89 * @param fname Base name supplied by the user (without suffix).
90 * @param mpi MPI context (rank used for JSON per-rank filename).
91 * @param rank_part_fmt `printf`-style format used for the JSON rank-id component.
92 * @param read `true` for read (skips directory creation).
93 * @return Tuple `(finalFilePath, displayPath)` -- the display path is
94 * the JSON dir or the H5 file, depending on backend.
95 */
96 [[nodiscard]] std::tuple<std::string, std::string> ModifyFilePath(std::string fname, const MPIInfo &mpi, const std::string &rank_part_fmt = "%06d", bool read = false) const
97 {
98 if (type == "JSON")
99 {
100 std::filesystem::path outPath;
101 outPath = {fname + ".dir"};
102 if (!read)
103 std::filesystem::create_directories(outPath);
104 std::array<char, 512> BUF{};
105 std::sprintf(BUF.data(), rank_part_fmt.c_str(), mpi.rank);
106 fname = getStringForcePath(outPath / (std::string(BUF.data()) + ".json"));
107 return std::make_tuple(fname, getStringForcePath(outPath));
108 }
109 else if (type == "H5")
110 {
111
112 fname += ".dnds.h5";
113 std::filesystem::path outPath = fname;
114 if (!read)
115 std::filesystem::create_directories(outPath.parent_path() / ".");
116 return std::make_tuple(fname, fname);
117 }
118 else
119 {
120 DNDS_assert_info(false, "type of serializer not existent: " + type);
121 return std::make_tuple(std::string(""), std::string(""));
122 }
123 }
124 };
125
126}
pybind11-style configuration registration with macro-based field declaration and namespace-scoped tag...
#define DNDS_FIELD(name_, desc_,...)
Register a field inside a DNDS_DECLARE_CONFIG body.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
Definition Errors.hpp:117
JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
Base types and abstract interface for array serialization.
MPI-parallel HDF5 serializer implementing the SerializerBase interface.
Per-rank JSON serializer implementing the SerializerBase interface.
EnumValuesTag enum_values(std::vector< std::string > vals)
Create an enum allowed-values tag.
RangeTag range(double min)
Create a minimum-only range constraint.
ssp< SerializerBase > SerializerBaseSSP
std::string getStringForcePath(const std::filesystem::path::string_type &v)
Portable conversion of a platform-native path string to std::string.
Definition Defines.hpp:635
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
Definition MPI.hpp:231
Config-backed factory selecting between JSON and HDF5 serializers.
int hdfDeflateLevel
HDF5 gzip deflate level (0 = off, 9 = max).
int hdfChunkSize
HDF5 chunk size (0 = library-chosen auto).
std::tuple< std::string, std::string > ModifyFilePath(std::string fname, const MPIInfo &mpi, const std::string &rank_part_fmt="%06d", bool read=false) const
Expand a user-supplied base file name into the backend-specific path layout.
bool hdfCollOnMeta
Use collective HDF5 I/O for metadata (usually safe).
std::string type
Backend selector: "JSON" or "H5".
SerializerBaseSSP BuildSerializer(const MPIInfo &mpi) const
Instantiate the selected serializer and apply its tunables.
bool hdfCollOnData
Use collective HDF5 I/O for data arrays.
SerializerFactory(std::string _type)
Construct with a specific backend name; other fields stay at defaults.
int jsonBinaryDeflateLevel
Compression level used by the JSON backend's binary codec.
bool jsonUseCodecOnUInt8
Whether to apply the byte-codec to uint8 arrays in JSON (faster writes).