From 4789dccda664cb9ecd0875da3453aabd25541b44 Mon Sep 17 00:00:00 2001 From: Olivier Parcollet Date: Wed, 21 May 2014 17:47:54 +0200 Subject: [PATCH] parameters : small details - an include missing on OS X - change serialization in the general case where hdf5 can be used, (version of hdf5 high enough) to use only one buffer, not a buffer per field. - put back the mpi_param example. --- test/triqs/parameters/mpi_param.cpp | 3 --- triqs/parameters/_field.hpp | 18 ++++++++------ triqs/parameters/parameters.cpp | 1 + triqs/parameters/parameters.hpp | 38 +++++++++++++++++++++-------- triqs/utility/serialization.hpp | 8 +++--- 5 files changed, 43 insertions(+), 25 deletions(-) diff --git a/test/triqs/parameters/mpi_param.cpp b/test/triqs/parameters/mpi_param.cpp index 987ea4d0..49a140a8 100644 --- a/test/triqs/parameters/mpi_param.cpp +++ b/test/triqs/parameters/mpi_param.cpp @@ -26,12 +26,9 @@ int main(int argc, char* argv[]) { P["d"] = 2.7; P["s"] = std::string("-14.3"); } -/* - * WITH SERIALIZATION std::cout << "Before bcast rank " << world.rank() << " : " << P << std::endl ; boost::mpi::broadcast(world,P,0); std::cout << "After bcast rank " << world.rank() << " : " << P << std::endl ; -*/ return 0; } diff --git a/triqs/parameters/_field.hpp b/triqs/parameters/_field.hpp index 5594a4f4..3c1aab71 100644 --- a/triqs/parameters/_field.hpp +++ b/triqs/parameters/_field.hpp @@ -48,7 +48,7 @@ namespace params { #define TRIQS_UTIL_OPAQUE_OBJECT_PREDEFINED_CAST \ (int)(long)(long long)(unsigned int)(unsigned long)(unsigned long long)(double)(bool)(std::string) - // the type actually stored + // the type actually stored template struct storage_t_impl : std::conditional::value, long, T>{}; template using storage_t = typename storage_t_impl>::type; @@ -109,14 +109,14 @@ namespace params { std::string name_; // for_error_messages bool modified = false; bool no_default_value = false; - + // only parameters will construct _field template _field(T obj, std::string n, bool without_default_value) : index(typeid(storage_t)), p(new _data_impl>{std::move(obj)}), name_(n), no_default_value(without_default_value) { type_names.insert({index, get_triqs_hdf5_data_scheme(storage_t{})}); } - + std::string type_name() const { return type_name(index); } static std::string type_name(std::type_index i); @@ -125,8 +125,8 @@ namespace params { template bool has_type() const { return index == typeid(T); } public: -#ifdef TRIQS_SERIALIZATION_WITH_BOOST - _field() : index(typeid(void)) {} // BREAKS invariant : only used for BOOST serialization. +#ifdef TRIQS_SERIALIZATION_WITH_HDF5_IMPOSSIBLE + _field() : index(typeid(void)) {} // BREAKS invariant : only used for BOOST serialization failsafe mode. #endif _field(_field &&c) = default; _field(_field const &x) : index(x.index), p(x.p ? x.p->clone() : nullptr), name_(x.name_), modified(x.modified), no_default_value(x.no_default_value) {} // regular type @@ -137,7 +137,7 @@ namespace params { template _field &operator=(RHS rhs) { // pass by value (sink) modified = true; using S_t = storage_t; - if (index != typeid(S_t)) { + if (index != typeid(S_t)) { TRIQS_RUNTIME_ERROR << "Field "<< name_<<" is of type "<< type_name(index)<<". I can not put a " << type_name(typeid(S_t)) << " into it."; } p.reset(new _data_impl{std::move(rhs)}); @@ -145,7 +145,7 @@ namespace params { } // rewrite a few cases for practical convenience ... - _field &operator=(int rhs) { // a special case where we can correct : int -> double + _field &operator=(int rhs) { // a special case where we can correct : int -> double if (index == typeid(double)) return operator=(double(rhs)); return operator=(long(rhs));// beware infinite loop! Works because int != long ... Clean this ... } @@ -169,7 +169,7 @@ namespace params { /// Is a modification required for this field bool is_modification_required() const { return no_default_value && (!modified); } - + #ifdef TRIQS_WITH_PYTHON_SUPPORT /// Convertions python <-> C++ bool from_python_convertible(PyObject *ob) const { return p->from_python_convertible(ob); } @@ -182,6 +182,7 @@ namespace params { BOOST_PP_SEQ_FOR_EACH(CAST_OPERATOR, nil, TRIQS_UTIL_OPAQUE_OBJECT_PREDEFINED_CAST); #undef CAST_OPERATOR +#ifdef TRIQS_SERIALIZATION_WITH_HDF5_IMPOSSIBLE // ----- Boost serialisation template void save(Archive &ar, const unsigned int version) const { @@ -194,6 +195,7 @@ namespace params { p->deserialize(s); } BOOST_SERIALIZATION_SPLIT_MEMBER(); +#endif friend std::ostream &operator<<(std::ostream &out, _field const &ob) { return ob.p->print(out); } diff --git a/triqs/parameters/parameters.cpp b/triqs/parameters/parameters.cpp index 417600a5..e434bb24 100644 --- a/triqs/parameters/parameters.cpp +++ b/triqs/parameters/parameters.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace triqs { namespace params { diff --git a/triqs/parameters/parameters.hpp b/triqs/parameters/parameters.hpp index 3d64c4e0..d5f0fd5a 100644 --- a/triqs/parameters/parameters.hpp +++ b/triqs/parameters/parameters.hpp @@ -31,14 +31,14 @@ namespace params { * DOC to be written. * * Provide a form for program parameters. - * + * * Fields of the form can be added with add_field method (only in C++), with a name, a type, a doc, and optionally a default value. - * + * * They can be retrieved from and put into the form, using the [] operator, in C++ and python. - * - * The data is stored with a strict type checking at runtime, with some type collapse (all integers into a long, + * + * The data is stored with a strict type checking at runtime, with some type collapse (all integers into a long, * all string, const char * into a std::string, etc). - * + * * Basic type cast to basic types are provided. * * The class is boost-serializable and implements hdf5 I/O operations. @@ -48,9 +48,11 @@ namespace params { std::string key; _field f; std::string doc; +#ifdef TRIQS_SERIALIZATION_WITH_HDF5_IMPOSSIBLE template void serialize(Archive& ar, const unsigned int version) { ar& TRIQS_MAKE_NVP("key", key) & TRIQS_MAKE_NVP("f", f) & TRIQS_MAKE_NVP("doc", doc); } +#endif }; using _data_t = std::vector<_data_elem>; _data_t _data; @@ -59,7 +61,23 @@ namespace params { _data_t::const_iterator find(std::string const& key) const; friend class boost::serialization::access; - template void serialize(Archive& ar, const unsigned int version) { ar& TRIQS_MAKE_NVP("_data", _data); } +#ifdef TRIQS_SERIALIZATION_WITH_HDF5_IMPOSSIBLE + template void serialize(Archive& ar, const unsigned int version) { + ar& TRIQS_MAKE_NVP("_data", _data); + } +#else + // do it at once, with one buffer only. + template void save(Archive &ar, const unsigned int version) const { + std::string s = h5::serialize(*this); + ar << TRIQS_MAKE_NVP("seria_str", s); + } + template void load(Archive &ar, const unsigned int version) { + std::string s; + ar >> TRIQS_MAKE_NVP("seria_str", s); + *this = h5::deserialize(s); + } + BOOST_SERIALIZATION_SPLIT_MEMBER(); +#endif public: parameters(); @@ -88,13 +106,13 @@ namespace params { /// Does the form have the key ? bool has_key(std::string const& key) const; - /** + /** * Access the parameter key. * Key must be a valid key or a TRIQS_RUNTIME_ERROR is thrown. */ _field& operator[](const char * key); - /** + /** * Access the parameter key. * Key must be a valid key or a TRIQS_RUNTIME_ERROR is thrown. */ @@ -103,14 +121,14 @@ namespace params { /// generate help in form of a table of strings containing a list of required and optional parameters std::vector> generate_help(bool with_header = true) const; - /// help as a string + /// help as a string std::string help() const; /// hdf5 friend std::string get_triqs_hdf5_data_scheme(parameters const &) { return ""; } friend void h5_write(h5::group F, std::string const& subgroup_name, parameters const& p); friend void h5_read(h5::group F, std::string const& subgroup_name, parameters& p); - + /// Ostream friend std::ostream& operator<<(std::ostream& out, parameters const& p); diff --git a/triqs/utility/serialization.hpp b/triqs/utility/serialization.hpp index ace51587..4bedb0a1 100644 --- a/triqs/utility/serialization.hpp +++ b/triqs/utility/serialization.hpp @@ -20,14 +20,14 @@ ******************************************************************************/ #pragma once -#if defined(TRIQS_SERIALIZATION_USE_BOOST) or not H5_VERSION_GE(1,8,9) +#if defined(TRIQS_SERIALIZATION_DO_NOT_USE_HDF5) or not H5_VERSION_GE(1,8,9) + +#define TRIQS_SERIALIZATION_WITH_HDF5_IMPOSSIBLE #include "./boost_serialization.hpp" -#define TRIQS_SERIALIZATION_WITH_BOOST #else -#include "../h5/serialization.hpp" -#define TRIQS_SERIALIZATION_WITH_HDF5 +#include "../h5/serialization.hpp" namespace triqs { using h5::serialize; using h5::deserialize;