add first parts of cereal extension

This commit is contained in:
Christian Zimmermann 2023-02-27 20:09:06 +01:00
parent 82fab9f7dc
commit 36a22f51de
24 changed files with 379 additions and 16 deletions

View file

@ -51,6 +51,23 @@ else()
set(ENABLE_hdf5 TRUE CACHE BOOL "enable hdf5")
endif()
if(DEFINED ENABLE_cereal)
set(ENABLE_cereal ${ENABLE_cereal} CACHE BOOL "enable hdf5")
else()
set(ENABLE_cereal TRUE CACHE BOOL "enable hdf5")
endif()
find_package(cereal QUIET)
if(cereal_FOUND)
message(STATUS "found cereal")
add_definitions(-DHAVE_CEREAL)
else()
message(STATUS "no cereal")
if(ENABLE_cereal)
message(FATAL_ERROR "cereal has been enabled but the cereal library has not been found")
endif()
endif()
add_definitions(-DVERSION="${VERSION}")
add_definitions(-DGIT_COMMIT="${GIT_HASH}")
add_definitions(-DCXX_FLAGS="${CMAKE_CXX_FLAGS}")

View file

@ -8,4 +8,8 @@ if(ENABLE_hdf5)
add_subdirectory(opt/hdf5)
endif()
if(ENABLE_cereal)
add_subdirectory(opt/cereal)
endif()
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz)

View file

@ -29,6 +29,8 @@ namespace CNORXZ
virtual const_iterator cbegin() const override;
virtual const_iterator cend() const override;
virtual bool isView() const override;
SERIALIZATION_FUNCTIONS;
private:
Vector<T> mCont;

View file

@ -38,4 +38,15 @@
#define IS_SAME(a,b) std::is_same<a,b>::value
#define IS_NOT_SAME(a,b) (not std::is_same<a,b>::value)
#ifdef HAVE_CEREAL
#define SERIALIZATION_FUNCTIONS template <class Archive> void save(Archive& ar) const; \
template <class Archive> void load(Archive& ar)
#define SERIALIZATION_FUNCTIONS_NOPUB friend class cereal::access; \
template <class Archive> void save(Archive& ar) const; \
template <class Archive> void load(Archive& ar)
#else
#define SERIALIZATION_FUNCTIONS
#define SERIALIZATION_FUNCTIONS_NOPUB
#endif
#endif

View file

@ -100,7 +100,11 @@ namespace CNORXZ
CRange(const CRange& in) = delete;
CRange(SizeT size);
virtual Vector<Uuid> key() const override final;
SizeT mSize = 0;
SERIALIZATION_FUNCTIONS_NOPUB;
};
template <>

View file

@ -529,15 +529,15 @@ namespace CNORXZ
template <class... Ranges>
void MRangeFactory<Ranges...>::make()
{
Vector<Uuid> key = iter<0,sizeof...(Ranges)>
( [&](auto i) { return std::get<i>( mRs ); },
[](const auto&... e) { return Vector<Uuid> { e->id()... }; } );
const auto& info = typeid(MRange<Ranges...>);
if(mRef != nullptr) {
mProd = this->fromCreated(info, {mRef->id()});
}
mProd = this->fromCreated(info, key);
if(mProd == nullptr) {
RangePtr key = mProd = std::shared_ptr<MRange<Ranges...>>
mProd = std::shared_ptr<MRange<Ranges...>>
( new MRange<Ranges...>( mRs ) );
if(mRef != nullptr) { key = mRef; }
this->addToCreated(info, { key->id() }, mProd);
this->addToCreated(info, key, mProd);
}
}
@ -620,7 +620,16 @@ namespace CNORXZ
);
return MRangeFactory<Ranges...>( rs ).create();
}
template <class... Ranges>
Vector<Uuid> MRange<Ranges...>::key() const
{
Vector<Uuid> key = iter<0,sizeof...(Ranges)>
( [&](auto i) { return std::get<i>( mRs ); },
[](const auto&... e) { return Vector<Uuid> { e->id()... }; } );
return key;
}
/************************
* MRange (private) *
************************/

View file

@ -187,13 +187,15 @@ namespace CNORXZ
SizeT getMeta(const MetaType& metaPos) const;
protected:
MRange() = delete;
MRange() = default;
MRange(const MRange& in) = delete;
MRange& operator=(const MRange& in) = delete;
MRange(const Tuple<Sptr<Ranges>...>& rs);
Tuple<Sptr<Ranges>...> mRs;
Arr<RangePtr,NR> mA;
virtual Vector<Uuid> key() const override final;
private:
decltype(auto) mkA() const;

View file

@ -8,6 +8,10 @@
#include "memory/memory.h"
#include "memory/memory.cc.h"
#ifdef HAVE_CEREAL
#include <cereal/access.hpp>
#endif
namespace CNORXZ
{
@ -17,9 +21,12 @@ namespace CNORXZ
RangeFactoryBase() = default;
virtual ~RangeFactoryBase() = default;
RangePtr create();
static RangePtr getRegistered(const TypeInfo& info, const RangePtr& r);
// check if range with uuid of r exists; if yes, return existing one, else add r and return it
protected:
virtual void make() = 0;
@ -36,9 +43,6 @@ namespace CNORXZ
};
Sptr<RangeFactoryBase> createRangeFactory(const char** dp);
Sptr<RangeFactoryBase> createSingleRangeFactory(const Vector<char>*& d, int metaType, SizeT size);
class RangeBase
{
public:
@ -70,6 +74,9 @@ namespace CNORXZ
RangeBase();
RangeBase(const RangePtr& rel);
virtual Vector<Uuid> key() const = 0;
// delete copy/move???
Uuid mId = {0,0};
Wptr<RangeBase> mThis;

View file

@ -295,7 +295,13 @@ namespace CNORXZ
space.insert(space.end(), rx->mSpace.begin(), rx->mSpace.end());
return URangeFactory<MetaType>( space ).create();
}
template <typename MetaType>
Vector<Uuid> URange<MetaType>::key() const
{
return Vector<Uuid> { this->id() };
}
/*******************
* Range Casts *
*******************/

View file

@ -104,12 +104,16 @@ namespace CNORXZ
private:
URange() = delete;
URange() = default;
URange(const URange& in) = delete;
URange(const Vector<MetaType>& space);
URange(Vector<MetaType>&& space);
Vector<MetaType> mSpace;
virtual Vector<Uuid> key() const override final;
SERIALIZATION_FUNCTIONS_NOPUB;
};
template <typename MetaType>

View file

@ -108,6 +108,7 @@ namespace CNORXZ
Vector<RangePtr> mRVec;
RangePtr mRef;
};
class YRange : public RangeInterface<YRange>
@ -128,12 +129,16 @@ namespace CNORXZ
private:
YRange() = delete;
YRange() = default;
YRange(const YRange& a) = delete;
YRange(const Vector<RangePtr>& rvec);
YRange(Vector<RangePtr>&& rvec);
Vector<RangePtr> mRVec;
virtual Vector<Uuid> key() const override final;
SERIALIZATION_FUNCTIONS_NOPUB;
};
RangePtr yrange(const Vector<RangePtr>& rs);

View file

@ -191,6 +191,11 @@ namespace CNORXZ
auto rx = rangeCast<CRange>(r);
return CRangeFactory( this->size() + rx->size() ).create();
}
Vector<Uuid> CRange::key() const
{
return Vector<Uuid> { this->id() };
}
/*******************
* Range Casts *

View file

@ -35,6 +35,15 @@ namespace CNORXZ
sCreated[info.hash_code()][rids] = r;
}
RangePtr RangeFactoryBase::getRegistered(const TypeInfo& info, const RangePtr& r)
{
auto& rx = sCreated[info.hash_code()][r->key()];
if(rx == nullptr){
rx = r;
}
return rx;
}
/******************
* RangeBase *
******************/

View file

@ -505,6 +505,14 @@ namespace CNORXZ
return YRangeFactory( rvec ).create();
}
Vector<Uuid> YRange::key() const
{
Vector<Uuid> key(mRVec.size());
std::transform(mRVec.begin(), mRVec.end(), key.begin(),
[&](const RangePtr& r) { return r->id(); } );
return key;
}
YRange::YRange(const Vector<RangePtr>& rvec) : mRVec(rvec) {}
YRange::YRange(Vector<RangePtr>&& rvec) : mRVec(std::forward<Vector<RangePtr>>(rvec)) {}

View file

@ -0,0 +1,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_subdirectory(tests)
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz/cereal)

View file

@ -1 +0,0 @@
coming soon

View file

@ -0,0 +1,28 @@
#ifndef __cxz_cereal_array_cc_h__
#define __cxz_cereal_array_cc_h__
#include "base/base.h"
#include "array/marray.h"
#include <cereal/cereal.hpp>
namespace CNORXZ
{
template <typename T>
template <class Archive>
void MArray<T>::save(Archive& ar) const
{
ar(cereal::make_nvp("range", AB::mRange));
ar(cereal::make_nvp("data", mCont));
}
template <typename T>
template <class Archive>
void MArray<T>::load(Archive& ar)
{
ar(cereal::make_nvp("range", AB::mRange));
ar(cereal::make_nvp("data", mCont));
}
}
#endif

View file

@ -0,0 +1,91 @@
#ifndef __cxz_cereal_ranges_cc_h__
#define __cxz_cereal_ranges_cc_h__
#include <cereal/cereal.hpp>
#include <cereal/types/vector.hpp>
#include "base/base.h"
#include "ranges/crange.h"
#include "ranges/urange.h"
#include "ranges/yrange.h"
namespace CNORXZ
{
/**************
* save *
**************/
template <class Archive>
void save(Archive& ar, const Uuid& id)
{
ar(CEREAL_NVP(id.i1));
ar(CEREAL_NVP(id.i2));
}
template <class Archive>
void CRange::save(Archive& ar) const
{
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("size", mSize));
}
template <class MetaT>
template <class Archive>
void URange<MetaT>::save(Archive& ar) const
{
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("meta", mSpace));
}
template <class Archive>
void YRange::save(Archive& ar) const
{
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("sub", mRVec));
}
/**************
* load *
**************/
template <class Archive>
void load(Archive& ar, Uuid& id)
{
ar(CEREAL_NVP(id.i1));
ar(CEREAL_NVP(id.i2));
}
template <class Archive>
void CRange::load(Archive& ar)
{
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("size", mSize));
CXZ_ASSERT(RangePtr(RB::mThis).get() == this, "got corrupted range data"); // yes, cereal is that awesome! :)
}
template <class MetaT>
template <class Archive>
void URange<MetaT>::load(Archive& ar)
{
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("meta", mSpace));
CXZ_ASSERT(RangePtr(RB::mThis).get() == this, "got corrupted range data");
}
template <class Archive>
void YRange::load(Archive& ar)
{
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("sub", mRVec));
CXZ_ASSERT(RangePtr(RB::mThis).get() == this, "got corrupted range data");
}
}
#endif

View file

@ -0,0 +1,38 @@
#ifndef __cxz_cereal_type_register_cc_h__
#define __cxz_cereal_type_register_cc_h__
#include "cer_ranges.cc.h"
#include <cereal/types/polymorphic.hpp>
CEREAL_REGISTER_TYPE(CNORXZ::CRange);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::CRange);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::SizeT>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::SizeT>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Int>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Int>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Double>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Double>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::String>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::String>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::SizeT>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::SizeT>>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::Int>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::Int>>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::Double>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::Double>>);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::String>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::String>>);
CEREAL_REGISTER_TYPE(CNORXZ::YRange);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::YRange);
#endif

View file

@ -0,0 +1,6 @@
#include "range_save_load.h"
#include "range_save_load.cc.h"
#include "cer_array.cc.h"
#include "cer_ranges.cc.h"
#include "cer_type_register.cc.h"

View file

@ -0,0 +1,22 @@
#ifndef __range_save_load_cc_h__
#define __range_save_load_cc_h__
#include "ranges/range_base.h"
#include "range_save_load.h"
namespace CNORXZ
{
namespace cer
{
template <class Archive>
RangePtr save_load(Archive& ar, RangePtr& r)
{
ar(r);
return r = RangeFactoryBase::getRegistered(r->type(), r);
}
}
}
#endif

View file

@ -0,0 +1,16 @@
#ifndef __range_save_load_h__
#define __range_save_load_h__
#include "base/base.h"
namespace CNORXZ
{
namespace cer
{
template <class Archive>
RangePtr save_load(Archive& ar, RangePtr& r);
}
}
#endif

View file

@ -0,0 +1,5 @@
add_executable(certest cereal_unit_test.cc)
add_dependencies(certest cnorxz)
target_link_libraries(certest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} cnorxz)
add_test(NAME certest COMMAND certest)

View file

@ -0,0 +1,59 @@
#include <cstdlib>
#include <iostream>
#include <sstream>
#include "gtest/gtest.h"
#include "cnorxz.h"
#include "cnorxz_cereal.h"
#include <cereal/archives/json.hpp>
namespace
{
using namespace CNORXZ;
class CerCRange_Test : public ::testing::Test
{
protected:
CerCRange_Test()
{
mSize = 7;
mR = CRangeFactory(mSize).create();
}
SizeT mSize;
RangePtr mR;
std::stringstream mS;
};
TEST_F(CerCRange_Test, Serialize)
{
{
cereal::JSONOutputArchive ar(mS);
ar(mR);
}
std::cout << mS.str() << std::endl;
RangePtr r = nullptr;
{
cereal::JSONInputArchive ar(mS);
ar(r);
}
EXPECT_EQ(r->size(), mR->size());
EXPECT_EQ(r->dim(), mR->dim());
auto i1 = r->begin();
auto i2 = mR->begin();
auto i1e = r->end();
auto i2e = mR->end();
for(; i1 != i1e; ++i1, ++i2){
EXPECT_TRUE(*i1 == *i2);
}
}
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}