DNDSR 0.1.0.dev1+gcd065ad
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"
10#include "ConfigParam.hpp"
11
12namespace DNDS::Serializer
13{
14 /**
15 * @brief Config-backed factory selecting between JSON and HDF5 serializers.
16 *
17 * @details Exposes the tunables of both backends under a single config
18 * schema so users can switch formats by changing one JSON field. See
19 * @ref DNDS_DECLARE_CONFIG body for the full list of fields.
20 */
22 {
23 /// @brief Backend selector: `"JSON"` or `"H5"`.
24 std::string type = "JSON";
25 /// @brief HDF5 gzip deflate level (0 = off, 9 = max).
27 /// @brief HDF5 chunk size (0 = library-chosen auto).
28 int hdfChunkSize = 0;
29 /// @brief Use collective HDF5 I/O for data arrays.
30 bool hdfCollOnData = false;
31 /// @brief Use collective HDF5 I/O for metadata (usually safe).
32 bool hdfCollOnMeta = true;
33 /// @brief Compression level used by the JSON backend's binary codec.
35 /// @brief Whether to apply the byte-codec to uint8 arrays in JSON (faster writes).
37
38 SerializerFactory() = default;
39 /// @brief Construct with a specific backend name; other fields stay at defaults.
40 SerializerFactory(const std::string &_type) : type(_type) {}
41
43 {
44 DNDS_FIELD(type, "Serializer backend: \"JSON\" or \"H5\"",
45 DNDS::Config::enum_values({"JSON", "H5"}));
46 DNDS_FIELD(hdfDeflateLevel, "HDF5 deflate compression level",
48 DNDS_FIELD(hdfChunkSize, "HDF5 chunk size (0=auto)",
50 DNDS_FIELD(hdfCollOnData, "HDF5 collective I/O on data arrays");
51 DNDS_FIELD(hdfCollOnMeta, "HDF5 collective I/O on metadata");
52 DNDS_FIELD(jsonBinaryDeflateLevel, "JSON binary deflate level",
54 DNDS_FIELD(jsonUseCodecOnUInt8, "Apply codec on uint8 arrays in JSON");
55 }
56
57 /// @brief Instantiate the selected serializer and apply its tunables.
58 /// @param mpi MPI context (used only by the H5 backend).
60 {
61 SerializerBaseSSP serializerP;
62 if (type == "JSON")
63 {
64 serializerP = std::make_shared<SerializerJSON>();
65 std::dynamic_pointer_cast<SerializerJSON>(serializerP)->SetUseCodecOnUint8(jsonUseCodecOnUInt8);
66 std::dynamic_pointer_cast<SerializerJSON>(serializerP)->SetDeflateLevel(jsonBinaryDeflateLevel);
67 }
68 else if (type == "H5")
69 {
70 serializerP = std::make_shared<SerializerH5>(mpi);
71 std::dynamic_pointer_cast<SerializerH5>(serializerP)->SetChunkAndDeflate(hdfChunkSize, hdfDeflateLevel);
72 std::dynamic_pointer_cast<SerializerH5>(serializerP)->SetCollectiveRW(hdfCollOnMeta, hdfCollOnData);
73 }
74 else
75 DNDS_assert_info(false, "type of serializer not existent: " + type);
76 return serializerP;
77 }
78
79 /**
80 * @brief Expand a user-supplied base file name into the backend-specific path layout.
81 *
82 * @details JSON uses one file per rank under a `<name>.dir/` directory
83 * (`<rank>.json`); H5 produces a single `<name>.dnds.h5` file.
84 *
85 * @param fname Base name supplied by the user (without suffix).
86 * @param mpi MPI context (rank used for JSON per-rank filename).
87 * @param rank_part_fmt `printf`-style format used for the JSON rank-id component.
88 * @param read `true` for read (skips directory creation).
89 * @return Tuple `(finalFilePath, displayPath)` -- the display path is
90 * the JSON dir or the H5 file, depending on backend.
91 */
92 std::tuple<std::string, std::string> ModifyFilePath(std::string fname, const MPIInfo &mpi, std::string rank_part_fmt = "%06d", bool read = false)
93 {
94 if (type == "JSON")
95 {
96 std::filesystem::path outPath;
97 outPath = {fname + ".dir"};
98 if (!read)
99 std::filesystem::create_directories(outPath);
100 char BUF[512];
101 std::sprintf(BUF, rank_part_fmt.c_str(), mpi.rank);
102 fname = getStringForcePath(outPath / (std::string(BUF) + ".json"));
103 return std::make_tuple(fname, getStringForcePath(outPath));
104 }
105 else if (type == "H5")
106 {
107
108 fname += ".dnds.h5";
109 std::filesystem::path outPath = fname;
110 if (!read)
111 std::filesystem::create_directories(outPath.parent_path() / ".");
112 return std::make_tuple(fname, fname);
113 }
114 else
115 {
116 DNDS_assert_info(false, "type of serializer not existent: " + type);
117 return std::make_tuple(std::string(""), std::string(""));
118 }
119 }
120 };
121
122}
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:113
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:630
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
Definition MPI.hpp:215
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).
bool hdfCollOnMeta
Use collective HDF5 I/O for metadata (usually safe).
std::string type
Backend selector: "JSON" or "H5".
bool hdfCollOnData
Use collective HDF5 I/O for data arrays.
SerializerBaseSSP BuildSerializer(const MPIInfo &mpi)
Instantiate the selected serializer and apply its tunables.
SerializerFactory(const std::string &_type)
Construct with a specific backend name; other fields stay at defaults.
std::tuple< std::string, std::string > ModifyFilePath(std::string fname, const MPIInfo &mpi, std::string rank_part_fmt="%06d", bool read=false)
Expand a user-supplied base file name into the backend-specific path layout.
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).