Skip to content

Commit

Permalink
Merge pull request #214 from DARMA-tasking/161-use-Reconstructor-for-…
Browse files Browse the repository at this point in the history
…containers-elements

#161 use reconstruction logic for std::vector
  • Loading branch information
jstrzebonski authored Oct 15, 2021
2 parents 50889a5 + c7d41a0 commit dc92754
Show file tree
Hide file tree
Showing 7 changed files with 525 additions and 98 deletions.
56 changes: 38 additions & 18 deletions src/checkpoint/container/list_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define INCLUDED_CHECKPOINT_CONTAINER_LIST_SERIALIZE_H

#include "checkpoint/common.h"
#include "checkpoint/dispatch/allocator.h"
#include "checkpoint/serializers/serializers_headers.h"
#include "checkpoint/container/container_serialize.h"

Expand All @@ -55,30 +56,49 @@ namespace checkpoint {

template <typename Serializer, typename ContainerT, typename ElmT>
inline typename std::enable_if_t<
not std::is_same<Serializer, checkpoint::Footprinter>::value,
void
> deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size
not std::is_same<Serializer, checkpoint::Footprinter>::value, void
>
deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size,
isCopyConstructible<ElmT>* = nullptr
) {
for (typename ContainerT::size_type i = 0; i < size; i++) {
#pragma GCC diagnostic push
#if !defined(__has_warning)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#elif __has_warning("-Wmaybe-uninitialized")
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
ElmT elm;
s | elm;
cont.push_back(std::move(elm));
#pragma GCC diagnostic pop
using Alloc = dispatch::Allocator<ElmT>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<ElmT>::CleanT>;

Alloc allocated;
auto* reconstructed = Reconstructor::construct(allocated.buf);
cont.resize(size, *reconstructed);
for (auto& val : cont) {
s | val;
}
}

template <typename Serializer, typename ContainerT, typename ElmT>
inline typename std::enable_if_t<
not std::is_same<Serializer, checkpoint::Footprinter>::value, void
>
deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size,
isNotCopyConstructible<ElmT>* = nullptr
) {
using Alloc = dispatch::Allocator<ElmT>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<ElmT>::CleanT>;

Alloc allocated;
for (typename ContainerT::size_type i = 0; i < size; ++i) {
auto* reconstructed = Reconstructor::construct(allocated.buf);
s | *reconstructed;
cont.emplace_back(std::move(*reconstructed));
}
}

template <typename Serializer, typename ContainerT, typename ElmT>
inline typename std::enable_if_t<
std::is_same<Serializer, checkpoint::Footprinter>::value,
void
> deserializeOrderedElems(
std::is_same<Serializer, checkpoint::Footprinter>::value, void
>
deserializeOrderedElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size
) { }

Expand Down
19 changes: 9 additions & 10 deletions src/checkpoint/container/map_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define INCLUDED_CHECKPOINT_CONTAINER_MAP_SERIALIZE_H

#include "checkpoint/common.h"
#include "checkpoint/dispatch/allocator.h"
#include "checkpoint/serializers/serializers_headers.h"
#include "checkpoint/container/container_serialize.h"

Expand All @@ -62,17 +63,15 @@ inline typename std::enable_if_t<
> deserializeEmplaceElems(
Serializer& s, ContainerT& cont, typename ContainerT::size_type size
) {
using Alloc = dispatch::Allocator<ElmT>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<ElmT>::CleanT>;

Alloc allocated;
for (typename ContainerT::size_type i = 0; i < size; i++) {
#pragma GCC diagnostic push
#if !defined(__has_warning)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#elif __has_warning("-Wmaybe-uninitialized")
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
ElmT elm;
s | elm;
cont.emplace(std::move(elm));
#pragma GCC diagnostic pop
auto* reconstructed = Reconstructor::construct(allocated.buf);
s | *reconstructed;
cont.emplace(std::move(*reconstructed));
}
}

Expand Down
101 changes: 80 additions & 21 deletions src/checkpoint/container/vector_serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#define INCLUDED_CHECKPOINT_CONTAINER_VECTOR_SERIALIZE_H

#include "checkpoint/common.h"
#include "checkpoint/dispatch/allocator.h"
#include "checkpoint/dispatch/dispatch.h"
#include "checkpoint/dispatch/reconstructor.h"
#include "checkpoint/serializers/serializers_headers.h"

#include <vector>
Expand All @@ -53,43 +56,80 @@ namespace checkpoint {

template <typename SerializerT, typename T, typename VectorAllocator>
typename std::enable_if_t<
not std::is_same<SerializerT, checkpoint::Footprinter>::value,
void
> serializeVectorMeta(SerializerT& s, std::vector<T, VectorAllocator>& vec) {
not std::is_same<SerializerT, checkpoint::Footprinter>::value, SerialSizeType
>
serializeVectorMeta(SerializerT& s, std::vector<T, VectorAllocator>& vec) {
SerialSizeType vec_capacity = vec.capacity();
s | vec_capacity;
vec.reserve(vec_capacity);

SerialSizeType vec_size = vec.size();
s | vec_size;
return vec_size;
}

template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
isDefaultConsType<T>* = nullptr
) {
vec.resize(vec_size);
}

template <typename SerializerT, typename T, typename VectorAllocator>
typename std::enable_if_t<
std::is_same<SerializerT, checkpoint::Footprinter>::value,
void
> serializeVectorMeta(SerializerT& s, std::vector<T, VectorAllocator>& vec) {
s.countBytes(vec);
template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
isNotDefaultConsType<T>* = nullptr, isCopyConstructible<T>* = nullptr
) {
using Alloc = dispatch::Allocator<T>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<T>::CleanT>;

Alloc allocated;
auto* reconstructed = Reconstructor::construct(allocated.buf);
vec.resize(vec_size, *reconstructed);
}

template <typename Serializer, typename T, typename VectorAllocator>
void serialize(Serializer& s, std::vector<T, VectorAllocator>& vec) {
serializeVectorMeta(s, vec);
dispatch::serializeArray(s, vec.data(), vec.size());
template <typename T, typename VectorAllocator>
void constructVectorData(
SerialSizeType const vec_size, std::vector<T, VectorAllocator>& vec,
isNotDefaultConsType<T>* = nullptr, isNotCopyConstructible<T>* = nullptr
) {
using Alloc = dispatch::Allocator<T>;
using Reconstructor =
dispatch::Reconstructor<typename dispatch::CleanType<T>::CleanT>;

// make sure to account for reserved space when footprinting
s.addBytes(sizeof(T) * (vec.capacity() - vec.size()));
Alloc allocated;
for (SerialSizeType i = 0; i < vec_size; ++i) {
auto* reconstructed = Reconstructor::construct(allocated.buf);
vec.emplace_back(std::move(*reconstructed));
}
}

template <typename Serializer, typename VectorAllocator>
void serialize(Serializer& s, std::vector<bool, VectorAllocator>& vec) {
if (s.isFootprinting()) {
s.countBytes(vec);
return;
template <typename SerializerT, typename T, typename VectorAllocator>
typename std::enable_if_t<
not std::is_same<SerializerT, checkpoint::Footprinter>::value, void
>
serialize(SerializerT& s, std::vector<T, VectorAllocator>& vec) {
auto const vec_size = serializeVectorMeta(s, vec);

if (s.isUnpacking()) {
constructVectorData(vec_size, vec);
}

serializeVectorMeta(s, vec);
dispatch::serializeArray(s, vec.data(), vec.size());
}

template <typename SerializerT, typename VectorAllocator>
typename std::enable_if_t<
not std::is_same<SerializerT, checkpoint::Footprinter>::value, void
>
serialize(SerializerT& s, std::vector<bool, VectorAllocator>& vec) {
auto const vec_size = serializeVectorMeta(s, vec);

if (s.isUnpacking()) {
constructVectorData(vec_size, vec);
}

if (!s.isUnpacking()) {
for (bool elt : vec) {
Expand All @@ -104,6 +144,25 @@ void serialize(Serializer& s, std::vector<bool, VectorAllocator>& vec) {
}
}

template <typename SerializerT, typename T, typename VectorAllocator>
typename std::enable_if_t<
std::is_same<SerializerT, checkpoint::Footprinter>::value, void
>
serialize(SerializerT& s, std::vector<T, VectorAllocator>& vec) {
s.countBytes(vec);
dispatch::serializeArray(s, vec.data(), vec.size());
s.addBytes(sizeof(T) * (vec.capacity() - vec.size()));
}

template <typename SerializerT, typename VectorAllocator>
typename std::enable_if_t<
std::is_same<SerializerT, checkpoint::Footprinter>::value, void
>
serialize(SerializerT& s, std::vector<bool, VectorAllocator>& vec) {
s.countBytes(vec);
return;
}

} /* end namespace checkpoint */

#endif /*INCLUDED_CHECKPOINT_CONTAINER_VECTOR_SERIALIZE_H*/
64 changes: 64 additions & 0 deletions src/checkpoint/dispatch/allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
//@HEADER
// *****************************************************************************
//
// allocator.h
// DARMA Toolkit v. 1.0.0
// DARMA/checkpoint => Serialization Library
//
// Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC
// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
// Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact [email protected]
//
// *****************************************************************************
//@HEADER
*/

#if !defined INCLUDED_CHECKPOINT_DISPATCH_ALLOCATOR_H
#define INCLUDED_CHECKPOINT_DISPATCH_ALLOCATOR_H

#include "checkpoint/dispatch/dispatch.h"

#include <memory>

namespace checkpoint { namespace dispatch {

template <typename T>
struct Allocator {
Allocator() : buf{Standard::template allocate<T>()} { }
~Allocator() { std::allocator<T>{}.deallocate(reinterpret_cast<T*>(buf), 1); }

SerialByteType* buf;
};

}} // namespace checkpoint::dispatch

#endif /*INCLUDED_CHECKPOINT_DISPATCH_ALLOCATOR_H*/
Loading

0 comments on commit dc92754

Please sign in to comment.