aaragon wrote:
Hello everyone,
I've been trying to create a simple way to serialize C++ objects so I
can send messages among different processors (using MPI). Something
very simple is shown below:
template <class StorageType>
void Send(StorageType& c, int dest, int tag, MPI_Comm comm) {
why not "const StorageType&" ?
typedef typename StorageType::ValueType ValueType;
int size = c.size()*sizeof(ValueType);
char* buffer[size];
^^^^^^^^^^^^ not sure if this is standard C++ yet.
memcpy(buffer, &c[0], size);
MPI_Send(&buffer, size, MPI_BYTE, dest, tag, comm);
Why not just write it like:
MPI_Send(
reinterpret_cast<const char*>(&c[0]),
size, MPI_BYTE, dest, tag, comm
);
... although you still don't deal with endian issues.
}
I tested the templated function with arrays of integers and it works
fine. However, when I try to use the dynamic_bitset provided by the
boost library, I cannot pass a reference to c[0] because operator& is
private for that class. Is there another efficient way to do a bitwise
copy???
Sounds like you need to do somthing very different for various different
type.
Usual way to do this is using a "traits" class and specialization.
BTW, you have some serious deficiencies in your serialization as you
have written it. It depends on the receiver to have the same endianness
as the sender.
Here is the beginnings of what I am alluding to.
template <typename T>
struct serialization_traits; // empty class for unknown types.
template <>
struct serialization_traits<int> : serialization_traits_pod<int> {};
template <>
struct serialization_traits<char> : serialization_traits_pod<char> {};
template <typename T>
struct serialization_traits< std::vector<T> > :
serialization_traits_container< std::vector<T> > {};
here, serialization_traits_pod, serialization_traits_container etc will
need to define methods that then allow you to do:
template <class StorageType>
void Send(StorageType& c, int dest, int tag, MPI_Comm comm) {
typedef typename serialization_traits<StorageType>::ValueType
ValueType;
typename serialization_traits<StorageType>::Serializer
serializer(c);
MPI_Send(c.buffer(), c.size(), MPI_BYTE, dest, tag, comm);
}
I could create a traits class as you suggested. It is just that I
simple. I just needed to create a buffer to pass to the MPI function
but it didn't work with the bitset data structure. I still don't know
of temporary copy anyways.