diff --git a/include/openPMD/auxiliary/JSON.hpp b/include/openPMD/auxiliary/JSON.hpp index 8c2551fe0a..223dfbde87 100644 --- a/include/openPMD/auxiliary/JSON.hpp +++ b/include/openPMD/auxiliary/JSON.hpp @@ -21,6 +21,12 @@ #pragma once +#include "openPMD/config.hpp" + +#if openPMD_HAVE_MPI +#include +#endif + #include namespace openPMD @@ -61,5 +67,12 @@ namespace json */ std::string merge(std::string const &defaultValue, std::string const &overwrite); + +#if openPMD_HAVE_MPI + std::string merge( + std::string const &defaultValue, + std::string const &overwrite, + MPI_Comm); +#endif } // namespace json } // namespace openPMD diff --git a/src/auxiliary/JSON.cpp b/src/auxiliary/JSON.cpp index d15412302d..b635bad1e7 100644 --- a/src/auxiliary/JSON.cpp +++ b/src/auxiliary/JSON.cpp @@ -597,11 +597,22 @@ merge(nlohmann::json &defaultVal, nlohmann::json const &overwrite) return defaultVal; } -std::string merge(std::string const &defaultValue, std::string const &overwrite) +template +std::string merge_impl( + std::string const &defaultValue, + std::string const &overwrite, + MPI_Comm_t &&...comm) { - auto [res, returnFormat] = - parseOptions(defaultValue, /* considerFiles = */ false); - merge(res, parseOptions(overwrite, /* considerFiles = */ false).config); + auto res = parseOptions( + defaultValue, + std::forward(comm)..., + /* considerFiles = */ true) + .config; + auto [second, returnFormat] = parseOptions( + overwrite, + std::forward(comm)..., + /* considerFiles = */ true); + merge(res, second); switch (returnFormat) { case SupportedLanguages::JSON: @@ -617,6 +628,21 @@ std::string merge(std::string const &defaultValue, std::string const &overwrite) throw std::runtime_error("Unreachable!"); } +std::string merge(std::string const &defaultValue, std::string const &overwrite) +{ + return merge_impl(defaultValue, overwrite); +} + +#if openPMD_HAVE_MPI +std::string merge( + std::string const &defaultValue, + std::string const &overwrite, + MPI_Comm comm) +{ + return merge_impl(defaultValue, overwrite, comm); +} +#endif + nlohmann::json & filterByTemplate(nlohmann::json &defaultVal, nlohmann::json const &positiveMask) { diff --git a/src/binding/python/Series.cpp b/src/binding/python/Series.cpp index 59068c2728..7902774856 100644 --- a/src/binding/python/Series.cpp +++ b/src/binding/python/Series.cpp @@ -408,12 +408,7 @@ Look for the WriteIterations class for further documentation. return series; }); - m.def( - "merge_json", - &json::merge, - py::arg("default_value") = "{}", - py::arg("overwrite") = "{}", - R"END( + constexpr char const *docs_merge_json = &R"END( Merge two JSON/TOML datasets into one. Merging rules: @@ -445,5 +440,37 @@ users to overwrite default options, while keeping any other ones. * returns: The merged dataset, according to the above rules. If `defaultValue` was a JSON dataset, then as a JSON string, otherwise as a TOML string. - )END"); + )END"[1]; + + m.def( + "merge_json", + py::overload_cast( + &json::merge), + py::arg("default_value") = "{}", + py::arg("overwrite") = "{}", + docs_merge_json) +#if openPMD_HAVE_MPI + .def( + "merge_json", + [](std::string const &default_value, + std::string const &overwrite, + py::object &comm) { + auto variant = pythonObjectAsMpiComm(comm); + if (auto errorMsg = std::get_if(&variant)) + { + throw std::runtime_error("[merge_json] " + *errorMsg); + } + else + { + py::gil_scoped_release release; + return json::merge( + default_value, overwrite, std::get(variant)); + } + }, + py::arg("default_value") = "{}", + py::arg("overwrite") = "{}", + py::arg("comm"), + docs_merge_json) +#endif + ; }