MADNESS
0.10.1
|
Files | |
file | archive.cc |
Definitions of serialization functions. | |
file | archive.h |
Interface templates for the archives (serialization). | |
file | archive_type_names.cc |
Defines archive type names for supported (by default) types. | |
file | binary_fstream_archive.cc |
Implements an archive wrapping a binary filestream. | |
file | binary_fstream_archive.h |
Implements an archive wrapping a binary filestream. | |
file | buffer_archive.h |
Implements an archive wrapping a memory buffer. | |
file | mpi_archive.h |
Implements archives to serialize data for MPI. | |
file | parallel_archive.h |
Implements ParallelInputArchive and ParallelOutputArchive for parallel serialization of data. | |
file | text_fstream_archive.cc |
Implements an archive wrapping text filestream. | |
file | text_fstream_archive.h |
Implements an archive wrapping text filestream. | |
file | vector_archive.h |
Implements an archive wrapping an STL vector . | |
Macros | |
#define | ARCHIVE_REGISTER_TYPE(T, cooky) |
Used to associate a type with a cookie value inside archive. More... | |
#define | ARCHIVE_REGISTER_TYPE_AND_PTR(T, cooky) |
Used to associate a type and a pointer to the type with a cookie value inside archive. More... | |
#define | ARCHIVE_REGISTER_TYPE_AND_PTR_NAMES(T) |
Used to associate names with types and pointers to that type. More... | |
#define | ARCHIVE_REGISTER_TYPE_NAME(T) |
Used to associate names with types. More... | |
#define | ATI ::madness::archive::archive_typeinfo |
Alias for archive_typeinfo . More... | |
#define | ATN ::madness::archive::archive_type_names |
Alias for archive_type_names . More... | |
Functions | |
void | madness::archive::archive_initialize_type_names () |
Initializes the type names for the archives. More... | |
template<class Archive , class T > | |
std::enable_if_t< is_default_serializable< Archive, T >::value &&is_archive< Archive >::value, void > | madness::archive::default_serialize (const Archive &ar, const T &t) |
Redirect serialize(ar, t) to serialize(ar, &t, 1) for fundamental types. More... | |
template<class Archive , class T > | |
std::enable_if_t< is_output_archive< Archive >::value &&is_default_serializable< Archive, T >::value &&is_function_pointer_v< T >, void > | madness::archive::default_serialize (const Archive &ar, const T *t, unsigned int n) |
Serialize an array of fundamental stuff. More... | |
template<typename T > | |
const char * | madness::archive::get_type_name () |
Returns the name of the type, or unknown if not registered. More... | |
template<class Archive , class T > | |
std::enable_if_t< is_output_archive_v< Archive >, const Archive & > | madness::archive::operator& (const Archive &ar, const T &t) |
Redirect & to ArchiveImpl::wrap_store for output archives. More... | |
template<class Archive , class T > | |
std::enable_if_t< is_output_archive_v< Archive >, const Archive & > | madness::archive::operator<< (const Archive &ar, const T &t) |
Redirect << to ArchiveImpl::wrap_store for output archives. More... | |
template<class Archive , class T > | |
std::enable_if_t< is_input_archive_v< Archive >, const Archive & > | madness::archive::operator>> (const Archive &ar, const T &t) |
Redirect >> to ArchiveImpl::wrap_load for input archives. More... | |
template<class Archive , class T > | |
std::enable_if_t<(!is_default_serializable< Archive, T >::value &&has_nonmember_serialize_v< T, Archive >) &&is_archive< Archive >::value, void > | madness::archive::serialize (const Archive &ar, const T &t) |
Redirect serialize(ar,t) to ArchiveSerializeImpl for non-fundamental types. More... | |
template<class Archive , class T > | |
std::enable_if_t< ! is_default_serializable< Archive, T >::value &&is_archive< Archive >::value, void > | madness::archive::serialize (const Archive &ar, const T *t, unsigned int n) |
Serialize (or deserialize) an array of non-fundamental stuff. More... | |
template<class T > | |
archive_array< T > | madness::archive::wrap (const T *ptr, unsigned int n) |
Factory function to wrap a dynamically allocated pointer as a typed archive_array . More... | |
template<class T > | |
archive_array< unsigned char > | madness::archive::wrap_opaque (const T &t) |
Factory function to wrap a contiguous scalar as an opaque (uchar ) archive_array . More... | |
template<class T > | |
archive_array< unsigned char > | madness::archive::wrap_opaque (const T *ptr, unsigned int n) |
Factory function to wrap a pointer to contiguous data as an opaque (uchar ) archive_array . More... | |
template<class T > | |
archive_ptr< T > | madness::archive::wrap_ptr (T *p) |
Wrapper for pointers. More... | |
Variables | |
const char * | madness::archive::archive_type_names [256] |
The list of type names for use in archives. More... | |
function pointer serialization | |
| |
std::ptrdiff_t | madness::archive::fn_ptr_origin () |
template<typename T , typename = std::enable_if_t<std::is_function<T>::value || is_function_pointer<T>::value>> | |
std::ptrdiff_t | madness::archive::to_rel_fn_ptr (const T &fn) |
converts function or (free or static member) function pointer to the relative function pointer More... | |
template<typename T , typename = std::enable_if_t<std::is_member_function_pointer<T>::value>> | |
auto | madness::archive::to_rel_memfn_ptr (const T &fn) |
converts nonstatic member function pointer to the relative equivalent More... | |
template<typename T , typename = std::enable_if_t<is_function_pointer_v<T>>> | |
T | madness::archive::to_abs_fn_ptr (std::ptrdiff_t rel_fn_ptr) |
converts relative free or static member function pointer to the absolute function pointer More... | |
template<typename T , std::size_t N, typename = std::enable_if_t<std::is_member_function_pointer<std::remove_reference_t<T>>::value>> | |
auto | madness::archive::to_abs_memfn_ptr (std::array< std::ptrdiff_t, N > rel_fn_ptr) |
converts relative (nonstatic) member function pointer to the absolute function pointer More... | |
The programmer should not need to include madness/world/archive.h directly. Instead, include the header file for the actual archive (binary file, text/xml file, vector in memory, etc.) that is desired.
The interface and implementation are deliberately modelled, albeit loosely, upon the boost serialization class (thanks boost!). The major differences are that this archive class does not break cycles and does not automatically store unique copies of data referenced by multiple objects. Also, classes are responsbible for managing their own version information. At the lowest level, the interface to an archive also differs to facilitate vectorization and high-bandwidth data transfer. The implementation employs templates that are almost entirely inlined. This should enable low-overhead use of archives in applications, such as interprocess communication.
An archive is a uni-directional stream of typed data to/from disk, memory, or another process. Whether the stream is for input or for output, you can use the &
operator to transfer data to/from the stream. If you really want, you can also use the <<
or >>
for output or input, respectively, but there is no reason to do so. The &
operator chains just like <<
for cout
or >>
for cin
. You may discover in archive.h
other interfaces but you should not use them — use the & operator! The lower level interfaces will probably not, or only inconsistently, incorporate type information, and may even appear to work when they are not.
Unless type checking has not been implemented by an archive for reasons of efficiency (e.g., message passing) a C-string exception will be thrown on a type-mismatch when deserializing. End-of-file, out-of-memory, and others also generate string exceptions.
Fundamental types (see below), STL complex, vector, strings, pairs and maps, and tensors (int, long, float, double, float_complex, double_complex) all work without you doing anything, as do fixed-dimension arrays of the same (STL allocators are not presently accomodated). For example,
Deserializing is identical, except that you need to use an input archive, c.f.,
Variable dimension and dynamically allocated arrays do not have their dimension encoded in their type. The best way to (de)serialize them is to wrap them in an archive_array
as follows.
The wrap()
function template is a factory function to simplify instantiation of a correctly typed archive_array
template. Note that when deserializing, you must have first allocated the array — the above code can be used for both serializing and deserializing. If you want the memory to be automatically allocated consider using either an STL vector or a madness tensor.
To transfer the actual value of a pointer to a stream (is this really what you want?) then store an archive_ptr wrapping it. The factory function wrap_ptr()
assists in doing this, e.g., here for a function pointer
User-defined types require a little more effort. Three cases are distinguished.
We will examine each in turn, but we first need to discuss a little about the implementation.
When transfering an object obj
to/from an archive ar
with ar & obj
, you need to invoke the templated function
that then invokes other templated functions to redirect to input or output streams as appropriate, manage type checking, etc. We would now like to overload the behavior of these functions in order to accomodate your fancy object. However, function templates cannot be partially specialized. Following the technique recommended here (look for moral#2), each of the templated functions directly calls a member of a templated class. Classes, unlike functions, can be partially specialized, so it is easy to control and predict what is happening. Thus, in order to change the behavior of all archives for an object you just have to provide a partial specialization of the appropriate class(es). Do not overload any of the function templates.
Symmetric intrusive method
Many classes can use the same code for serializing and deserializing. If such a class can be modified, the cleanest way of enabling serialization is to add a templated method as follows.
Symmetric non-intrusive method
If a class with symmetric serialization cannot be modified, then you can define an external class template with the following signature in the madness::archive
namespace (where Obj
is the name of your type).
For example,
Non-symmetric non-intrusive
For classes that do not have symmetric (de)serialization you must define separate partial templates for the functions load
and store
with these signatures and again in the madness::archive
namespace.
First a simple, but artificial example.
Now a more complicated example that genuinely requires asymmetric load and store.First, a class definition for a simple linked list.
And this is how you (de)serialize it.
Given the above implementation of a linked list, you can (de)serialize an entire list using a single statement.
There are various options for objects that do not have a default constructor. The most appealing and totally non-intrusive approach is to define load/store functions for a pointer to the object. Then in the load method you can deserialize all of the information necessary to invoke the constructor and return a pointer to a new object.
Things that you know are contiguously stored in memory and are painful to serialize with full type safety can be serialized by wrapping opaquely as byte streams using the wrap_opaque()
interface. However, this should be regarded as a last resort.
To enable type checking for user-defined types you must register them with the system. There are 64 empty slots for user types beginning at cookie=128. Type checked archives (currently all except the MPI archive) store a cookie (byte with value 0-255) with each datum. Unknown (user-defined) types all end up with the same cookie indicating unkown — i.e., no type checking unless you register.
Two steps are required to register your own types (e.g., here for the types Foo
and Bar
)
madness/world/test_ar.cc
to see things in action.Presently provided are
std::fstream
) a file in text (XML).std::fstream
) a file in binary.std::vector<unsigned_char>
.WorldContainer
(madness/world/worlddc.h) and MADNESS Function
(mra/mra.h) objects, though any serializable object can employ it.The buffer and vector
archives are bitwise identical to the binary file archive.
Minimally, an archive must derive from either BaseInputArchive
or BaseOutputArchive
and define for arrays of fundamental types either a load
or store
method, as appropriate. Additional methods can be provided to manipulate the target stream. Here is a simple, but functional, implementation of a binary file archive.
#define ARCHIVE_REGISTER_TYPE | ( | T, | |
cooky | |||
) |
Used to associate a type with a cookie value inside archive.
Makes a specialization of archive_typeinfo
for type T
that specifies the correct cookie value.
[in] | T | The type. |
[in] | cooky | The cookie value. |
#define ARCHIVE_REGISTER_TYPE_AND_PTR | ( | T, | |
cooky | |||
) |
Used to associate a type and a pointer to the type with a cookie value inside archive.
[in] | T | The type. |
[in] | cooky | The cookie value. |
#define ARCHIVE_REGISTER_TYPE_AND_PTR_NAMES | ( | T | ) |
Used to associate names with types and pointers to that type.
[in] | T | The type. |
#define ARCHIVE_REGISTER_TYPE_NAME | ( | T | ) |
Used to associate names with types.
[in] | T | The type. |
#define ATI ::madness::archive::archive_typeinfo |
Alias for archive_typeinfo
.
#define ATN ::madness::archive::archive_type_names |
Alias for archive_type_names
.
void madness::archive::archive_initialize_type_names | ( | ) |
Initializes the type names for the archives.
References ARCHIVE_REGISTER_TYPE_AND_PTR_NAMES, madness::archive::archive_type_names, and madness::initialized().
Referenced by madness::archive::BaseArchive::BaseArchive(), and main().
|
inline |
Redirect serialize(ar, t)
to serialize(ar, &t, 1)
for fundamental types.
The function only appears (due to enable_if
) if T
is serializable and Archive
is an archive.
Archive | The archive type. |
T | The data type. |
[in] | ar | The archive. |
[in] | t | The data to be serialized. |
References madness::archive::default_serialize(), and MAD_ARCHIVE_DEBUG.
std::enable_if_t< is_output_archive<Archive>::value && is_default_serializable<Archive,T>::value && is_function_pointer_v<T>, void> madness::archive::default_serialize | ( | const Archive & | ar, |
const T * | t, | ||
unsigned int | n | ||
) |
Serialize an array of fundamental stuff.
The function only appears (via enable_if
) if T
is serializable and Archive
is an output archive.
Archive | The archive type. |
T | The type of data in the array. |
[in] | ar | The archive. |
[in] | t | Pointer to the start of the array. |
[in] | n | Number of data items to be serialized. |
References MAD_ARCHIVE_DEBUG, madness::archive::to_rel_fn_ptr(), and transform().
Referenced by madness::archive::default_serialize(), madness::archive::ArchiveLoadImpl< Archive, T, Enabler >::load(), madness::archive::ArchiveStoreImpl< Archive, T, Enabler >::store(), madness::archive::ArchiveImpl< Archive, archive_array< T > >::wrap_load(), and madness::archive::ArchiveImpl< Archive, archive_array< T > >::wrap_store().
std::ptrdiff_t madness::archive::fn_ptr_origin | ( | ) |
const char* madness::archive::get_type_name | ( | ) |
Returns the name of the type, or unknown if not registered.
T | The data type. |
References madness::archive::archive_type_names.
|
inline |
Redirect &
to ArchiveImpl::wrap_store
for output archives.
The function only appears (due to enable_if
) if Archive
is an output archive.
Archive | The archive type. |
T | The data type. |
[in] | ar | The archive. |
[in] | t | The data. |
References madness::archive::ArchiveImpl< Archive, T, Enabler >::wrap_store().
|
inline |
Redirect <<
to ArchiveImpl::wrap_store
for output archives.
The function only appears (due to enable_if
) if Archive
is an output archive.
Archive | The archive type. |
T | The data type. |
[in] | ar | The archive. |
[in] | t | The data. |
References MAD_ARCHIVE_DEBUG, madness::archive::ArchiveSerializeImpl< Archive, T, Enabler >::serialize(), and T().
|
inline |
Redirect >>
to ArchiveImpl::wrap_load
for input archives.
The function only appears (due to enable_if
) if Archive
is an input archive.
Archive | The archive type. |
T | The data type. |
[in] | ar | The archive. |
[in] | t | The data. |
References madness::archive::ArchiveImpl< Archive, T, Enabler >::wrap_load().
|
inline |
Redirect serialize(ar,t)
to ArchiveSerializeImpl
for non-fundamental types.
The function only appears (due to enable_if
) if T
is not serializable and Archive
is an archive.
Archive | The archive type. |
T | The data type. |
[in] | ar | The archive. |
[in] | t | The data to be serialized. |
std::enable_if_t< ! is_default_serializable<Archive,T>::value && is_archive<Archive>::value, void> madness::archive::serialize | ( | const Archive & | ar, |
const T * | t, | ||
unsigned int | n | ||
) |
Serialize (or deserialize) an array of non-fundamental stuff.
The function only appears (via enable_if
) if T
is not serializable and Archive
is an archive.
Archive | The archive type. |
T | The type of data in the array. |
[in] | ar | The archive. |
[in] | t | Pointer to the start of the array. |
[in] | n | Number of data items to be serialized. |
References MAD_ARCHIVE_DEBUG.
Referenced by madness::archive::ArchiveLoadImpl< Archive, T, Enabler >::load(), madness::archive::ArchiveStoreImpl< Archive, T, Enabler >::store(), madness::archive::ArchiveImpl< Archive, archive_array< T > >::wrap_load(), and madness::archive::ArchiveImpl< Archive, archive_array< T > >::wrap_store().
T madness::archive::to_abs_fn_ptr | ( | std::ptrdiff_t | rel_fn_ptr | ) |
converts relative free or static member function pointer to the absolute function pointer
[in] | fn | a relative function pointer |
References madness::archive::fn_ptr_origin(), and T().
auto madness::archive::to_abs_memfn_ptr | ( | std::array< std::ptrdiff_t, N > | rel_fn_ptr | ) |
converts relative (nonstatic) member function pointer to the absolute function pointer
[in] | fn | a relative function pointer |
References madness::archive::fn_ptr_origin().
std::ptrdiff_t madness::archive::to_rel_fn_ptr | ( | const T & | fn | ) |
converts function or (free or static member) function pointer to the relative function pointer
[in] | fn | a function or function pointer |
References madness::archive::fn_ptr_origin(), and T().
Referenced by madness::archive::default_serialize(), madness::archive::ArchiveSerializeImpl< Archive, resT(*)(paramT...), std::enable_if_t<!is_default_serializable_v< Archive, resT(*)(paramT...)> > >::serialize(), and madness::AmArg::set_func().
auto madness::archive::to_rel_memfn_ptr | ( | const T & | fn | ) |
converts nonstatic member function pointer to the relative equivalent
[in] | fn | a member function pointer |
References madness::archive::fn_ptr_origin(), and T().
Referenced by madness::archive::default_serialize(), and madness::archive::ArchiveSerializeImpl< Archive, resT(objT::*)(paramT...), std::enable_if_t<!is_default_serializable_v< Archive, resT(objT::*)(paramT...)> > >::serialize().
|
inline |
Factory function to wrap a dynamically allocated pointer as a typed archive_array
.
T | The data type. |
[in] | ptr | The pointer. |
[in] | n | The number of data elements in the array. |
Referenced by madness::archive::ArchiveLoadImpl< Archive, Key< NDIM > >::load(), madness::archive::ArchiveLoadImpl< Archive, std::array< T, N >, std::enable_if_t< is_serializable_v< Archive, T > > >::load(), madness::archive::ArchiveLoadImpl< Archive, std::string >::load(), madness::archive::ArchiveLoadImpl< Archive, std::vector< bool, Alloc > >::load(), madness::archive::ArchiveLoadImpl< Archive, std::vector< T, Alloc >, std::enable_if_t<!is_future< T >::value &&is_serializable_v< Archive, T > > >::load(), madness::archive::ArchiveLoadImpl< Archive, GenTensor< T > >::load(), madness::archive::ArchiveLoadImpl< Archive, Tensor< T > >::load(), madness::archive::ArchiveLoadImpl< BinaryFstreamInputArchive, Key< NDIM > >::load(), InputParameters::serialize(), madness::KeyChildIterator< NDIM >::serialize(), madness::SRConf< T >::serialize(), madness::TensorTrain< T >::serialize(), madness::archive::ArchiveStoreImpl< Archive, Key< NDIM > >::store(), madness::archive::ArchiveStoreImpl< Archive, std::array< T, N >, std::enable_if_t< is_serializable_v< Archive, T > > >::store(), madness::archive::ArchiveStoreImpl< Archive, std::string >::store(), madness::archive::ArchiveStoreImpl< Archive, std::vector< bool, Alloc > >::store(), madness::archive::ArchiveStoreImpl< Archive, std::vector< T, Alloc >, std::enable_if_t<!is_future< T >::value &&is_serializable_v< Archive, T > > >::store(), madness::archive::ArchiveStoreImpl< Archive, GenTensor< T > >::store(), madness::archive::ArchiveStoreImpl< Archive, Tensor< T > >::store(), test_in(), test_out(), madness::archive::ArchiveImpl< Archive, T[n], std::enable_if_t<!std::is_same_v< T, char > &&is_serializable_v< Archive, T > > >::wrap_load(), madness::archive::ArchiveImpl< ParallelInputArchive< localarchiveT >, T[n]>::wrap_load(), madness::archive::ArchiveImpl< Archive, T[n], std::enable_if_t<!std::is_same_v< T, char > &&is_serializable_v< Archive, T > > >::wrap_store(), and madness::archive::ArchiveImpl< ParallelOutputArchive< localarchiveT >, T[n]>::wrap_store().
|
inline |
Factory function to wrap a contiguous scalar as an opaque (uchar
) archive_array
.
T | The data type. |
[in] | t | The data. |
|
inline |
Factory function to wrap a pointer to contiguous data as an opaque (uchar
) archive_array
.
T | The data type. |
[in] | ptr | The pointer. |
[in] | n | The number of data elements in the array. |
archive_array
. References T().
Referenced by madness::detail::WorldPtr< T >::load_internal_(), madness::FunctionImpl< T, NDIM >::do_op_args< OPDIM >::serialize(), madness::LBNodeDeux< NDIM >::serialize(), madness::archive::ArchiveSerializeImpl< Archive, resT(*)(paramT...), std::enable_if_t<!is_default_serializable_v< Archive, resT(*)(paramT...)> > >::serialize(), madness::archive::ArchiveSerializeImpl< Archive, resT(objT::*)(paramT...), std::enable_if_t<!is_default_serializable_v< Archive, resT(objT::*)(paramT...)> > >::serialize(), madness::archive::archive_ptr< T >::serialize(), madness::detail::info_base< memfunT >::serialize(), madness::RemoteReference< T >::serialize(), madness::archive::ArchiveSerializeImpl< Archive, resT(objT::*)(paramT...) const, std::enable_if_t<!is_default_serializable_v< Archive, resT(objT::*)(paramT...) const > > >::serialize(), and madness::detail::WorldPtr< T >::store_internal_().
|
inline |
Wrapper for pointers.
T | The type of object being pointed to. |
[in] | p | The pointer. |
References p().
const char * madness::archive::archive_type_names |
The list of type names for use in archives.
Referenced by madness::archive::archive_initialize_type_names(), madness::archive::TextFstreamInputArchive::check_start_tag(), madness::archive::get_type_name(), madness::archive::TextFstreamOutputArchive::open(), madness::archive::ArchivePrePostImpl< Archive, T >::preamble_load(), and madness::archive::ArchivePrePostImpl< Archive, T >::preamble_store().