Commit 365d3d39 authored by Sujin Philip's avatar Sujin Philip

Implement DataSet Serialization

parent fd89dfc8
......@@ -340,6 +340,76 @@ extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit<
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
struct TypeString<vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "CS_Explicit<" +
TypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST>>::Get() + "_ST," +
TypeString<vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST>>::Get() + "_ST," +
TypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST," +
TypeString<vtkm::cont::ArrayHandle<vtkm::Id, OffsetST>>::Get() + "_ST>";
return name;
}
};
}
} // vtkm::cont
namespace diy
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
struct Serialization<vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
{
private:
using Type = vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
{
diy::save(bb, cs.GetName());
diy::save(bb, cs.GetNumberOfPoints());
diy::save(bb,
cs.GetShapesArray(vtkm::TopologyElementTagPoint{}, vtkm::TopologyElementTagCell{}));
diy::save(
bb, cs.GetNumIndicesArray(vtkm::TopologyElementTagPoint{}, vtkm::TopologyElementTagCell{}));
diy::save(
bb, cs.GetConnectivityArray(vtkm::TopologyElementTagPoint{}, vtkm::TopologyElementTagCell{}));
diy::save(
bb, cs.GetIndexOffsetArray(vtkm::TopologyElementTagPoint{}, vtkm::TopologyElementTagCell{}));
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
{
std::string name;
diy::load(bb, name);
vtkm::Id numberOfPoints = 0;
diy::load(bb, numberOfPoints);
vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST> shapes;
diy::load(bb, shapes);
vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST> counts;
diy::load(bb, counts);
vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST> connectivity;
diy::load(bb, connectivity);
vtkm::cont::ArrayHandle<vtkm::Id, OffsetST> offsets;
diy::load(bb, offsets);
cs = Type(name);
cs.Fill(numberOfPoints, shapes, counts, connectivity, offsets);
}
};
} // diy
#include <vtkm/cont/CellSetExplicit.hxx>
#endif //vtk_m_cont_CellSetExplicit_h
......@@ -396,4 +396,56 @@ vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType> make
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <typename CSType, typename AHValidCellIds>
struct TypeString<vtkm::cont::CellSetPermutation<CSType, AHValidCellIds>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"CS_Permutation<" + TypeString<CSType>::Get() + "," + TypeString<AHValidCellIds>::Get() + ">";
return name;
}
};
}
} // vtkm::cont
namespace diy
{
template <typename CSType, typename AHValidCellIds>
struct Serialization<vtkm::cont::CellSetPermutation<CSType, AHValidCellIds>>
{
private:
using Type = vtkm::cont::CellSetPermutation<CSType, AHValidCellIds>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
{
diy::save(bb, cs.GetName());
diy::save(bb, cs.GetFullCellSet());
diy::save(bb, cs.GetValidCellIds());
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
{
std::string name;
diy::load(bb, name);
CSType fullCS;
diy::load(bb, fullCS);
AHValidCellIds validCellIds;
diy::load(bb, validCellIds);
cs = make_CellSetPermutation(validCellIds, fullCS, name);
}
};
} // diy
#endif //vtk_m_cont_CellSetPermutation_h
......@@ -261,4 +261,65 @@ private:
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <typename ConnectivityST>
struct TypeString<vtkm::cont::CellSetSingleType<ConnectivityST>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"CS_Single<" + TypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST>";
return name;
}
};
}
} // vtkm::cont
namespace diy
{
template <typename ConnectivityST>
struct Serialization<vtkm::cont::CellSetSingleType<ConnectivityST>>
{
private:
using Type = vtkm::cont::CellSetSingleType<ConnectivityST>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
{
diy::save(bb, cs.GetName());
diy::save(bb, cs.GetNumberOfPoints());
diy::save(bb, cs.GetCellShape(0));
diy::save(bb, cs.GetNumberOfPointsInCell(0));
diy::save(
bb, cs.GetConnectivityArray(vtkm::TopologyElementTagPoint{}, vtkm::TopologyElementTagCell{}));
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
{
std::string name;
diy::load(bb, name);
vtkm::Id numberOfPoints = 0;
diy::load(bb, numberOfPoints);
vtkm::UInt8 shape;
diy::load(bb, shape);
vtkm::IdComponent count;
diy::load(bb, count);
vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST> connectivity;
diy::load(bb, connectivity);
cs = Type(name);
cs.Fill(numberOfPoints, shape, count, connectivity);
}
};
} // diy
#endif //vtk_m_cont_CellSetSingleType_h
......@@ -112,6 +112,54 @@ extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetStructured<3>;
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <vtkm::IdComponent DIMENSION>
struct TypeString<vtkm::cont::CellSetStructured<DIMENSION>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "CS_Structured<" + std::to_string(DIMENSION) + ">";
return name;
}
};
}
} // vtkm::cont
namespace diy
{
template <vtkm::IdComponent DIMENSION>
struct Serialization<vtkm::cont::CellSetStructured<DIMENSION>>
{
private:
using Type = vtkm::cont::CellSetStructured<DIMENSION>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
{
diy::save(bb, cs.GetName());
diy::save(bb, cs.GetPointDimensions());
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
{
std::string name;
diy::load(bb, name);
typename Type::SchedulingRangeType dims;
diy::load(bb, dims);
cs = Type(name);
cs.SetPointDimensions(dims);
}
};
} // diy
#include <vtkm/cont/CellSetStructured.hxx>
#endif //vtk_m_cont_CellSetStructured_h
......@@ -129,4 +129,30 @@ struct DynamicTransformTraits<vtkm::cont::CoordinateSystem>
} // namespace cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
namespace diy
{
template <>
struct Serialization<vtkm::cont::CoordinateSystem>
{
static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::CoordinateSystem& cs)
{
diy::save(bb, cs.GetName());
diy::save(bb, cs.GetData());
}
static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::CoordinateSystem& cs)
{
std::string name;
diy::load(bb, name);
vtkm::cont::ArrayHandleVirtualCoordinates array;
diy::load(bb, array);
cs = vtkm::cont::CoordinateSystem(name, array);
}
};
} // diy
#endif //vtk_m_cont_CoordinateSystem_h
......@@ -187,4 +187,102 @@ private:
} // namespace cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG,
typename FieldStorageList = VTKM_DEFAULT_STORAGE_LIST_TAG,
typename CellSetTypesList = VTKM_DEFAULT_CELL_SET_LIST_TAG>
struct SerializableDataSet
{
SerializableDataSet() = default;
explicit SerializableDataSet(const vtkm::cont::DataSet& dataset)
: DataSet(dataset)
{
}
vtkm::cont::DataSet DataSet;
};
}
} // vtkm::cont
namespace diy
{
template <typename FieldTypeList, typename FieldStorageList, typename CellSetTypesList>
struct Serialization<
vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypesList>>
{
private:
using Type = vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypesList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable)
{
const auto& dataset = serializable.DataSet;
vtkm::IdComponent numberOfCoordinateSystems = dataset.GetNumberOfCoordinateSystems();
diy::save(bb, numberOfCoordinateSystems);
for (vtkm::IdComponent i = 0; i < numberOfCoordinateSystems; ++i)
{
diy::save(bb, dataset.GetCoordinateSystem(i));
}
vtkm::IdComponent numberOfCellSets = dataset.GetNumberOfCellSets();
diy::save(bb, numberOfCellSets);
for (vtkm::IdComponent i = 0; i < numberOfCellSets; ++i)
{
diy::save(bb, dataset.GetCellSet(i).ResetCellSetList(CellSetTypesList{}));
}
vtkm::IdComponent numberOfFields = dataset.GetNumberOfFields();
diy::save(bb, numberOfFields);
for (vtkm::IdComponent i = 0; i < numberOfFields; ++i)
{
diy::save(
bb, vtkm::cont::SerializableField<FieldTypeList, FieldStorageList>(dataset.GetField(i)));
}
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& serializable)
{
auto& dataset = serializable.DataSet;
dataset = {}; // clear
vtkm::IdComponent numberOfCoordinateSystems = 0;
diy::load(bb, numberOfCoordinateSystems);
for (vtkm::IdComponent i = 0; i < numberOfCoordinateSystems; ++i)
{
vtkm::cont::CoordinateSystem coords;
diy::load(bb, coords);
dataset.AddCoordinateSystem(coords);
}
vtkm::IdComponent numberOfCellSets = 0;
diy::load(bb, numberOfCellSets);
for (vtkm::IdComponent i = 0; i < numberOfCellSets; ++i)
{
vtkm::cont::DynamicCellSetBase<CellSetTypesList> cells;
diy::load(bb, cells);
dataset.AddCellSet(vtkm::cont::DynamicCellSet(cells));
}
vtkm::IdComponent numberOfFields = 0;
diy::load(bb, numberOfFields);
for (vtkm::IdComponent i = 0; i < numberOfFields; ++i)
{
vtkm::cont::SerializableField<FieldTypeList, FieldStorageList> field;
diy::load(bb, field);
dataset.AddField(field.Field);
}
}
};
} // diy
#endif //vtk_m_cont_DataSet_h
......@@ -357,4 +357,79 @@ struct DynamicCellSetCheck<vtkm::cont::DynamicCellSetBase<CellSetList>>
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace diy
{
namespace internal
{
struct DynamicCellSetSerializeFunctor
{
template <typename CellSetType>
void operator()(const CellSetType& cs, BinaryBuffer& bb) const
{
diy::save(bb, vtkm::cont::TypeString<CellSetType>::Get());
diy::save(bb, cs);
}
};
template <typename CellSetTypes>
struct DynamicCellSetDeserializeFunctor
{
template <typename CellSetType>
void operator()(CellSetType,
vtkm::cont::DynamicCellSetBase<CellSetTypes>& dh,
const std::string& typeString,
bool& success,
BinaryBuffer& bb) const
{
if (!success && (typeString == vtkm::cont::TypeString<CellSetType>::Get()))
{
CellSetType cs;
diy::load(bb, cs);
dh = vtkm::cont::DynamicCellSetBase<CellSetTypes>(cs);
success = true;
}
}
};
} // internal
template <typename CellSetTypes>
struct Serialization<vtkm::cont::DynamicCellSetBase<CellSetTypes>>
{
private:
using Type = vtkm::cont::DynamicCellSetBase<CellSetTypes>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
{
obj.CastAndCall(internal::DynamicCellSetSerializeFunctor{}, bb);
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
{
std::string typeString;
diy::load(bb, typeString);
bool success = false;
vtkm::ListForEach(internal::DynamicCellSetDeserializeFunctor<CellSetTypes>{},
CellSetTypes{},
obj,
typeString,
success,
bb);
if (!success)
{
throw vtkm::cont::ErrorBadType("Error deserializing DynamicCellSet. Message TypeString: " +
typeString);
}
}
};
} // diy
#endif //vtk_m_cont_DynamicCellSet_h
......@@ -398,4 +398,90 @@ struct DynamicTransformTraits<vtkm::cont::Field>
} // namespace cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <typename TypeList = VTKM_DEFAULT_TYPE_LIST_TAG,
typename StorageList = VTKM_DEFAULT_STORAGE_LIST_TAG>
struct SerializableField
{
SerializableField() = default;
explicit SerializableField(const vtkm::cont::Field& field)
: Field(field)
{
}
vtkm::cont::Field Field;
};
}
} // vtkm::cont
namespace diy
{
template <typename TypeList, typename StorageList>
struct Serialization<vtkm::cont::SerializableField<TypeList, StorageList>>
{
private:
using Type = vtkm::cont::SerializableField<TypeList, StorageList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable)
{
const auto& field = serializable.Field;
diy::save(bb, field.GetName());
diy::save(bb, static_cast<int>(field.GetAssociation()));
if (field.GetAssociation() == vtkm::cont::Field::Association::CELL_SET)
{
diy::save(bb, field.GetAssocCellSet());
}
else if (field.GetAssociation() == vtkm::cont::Field::Association::LOGICAL_DIM)
{
diy::save(bb, field.GetAssocLogicalDim());
}
diy::save(bb, field.GetData().ResetTypeAndStorageLists(TypeList{}, StorageList{}));
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& serializable)
{
auto& field = serializable.Field;
std::string name;
diy::load(bb, name);
int assocVal = 0;
diy::load(bb, assocVal);
auto assoc = static_cast<vtkm::cont::Field::Association>(assocVal);
vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList> data;
if (assoc == vtkm::cont::Field::Association::CELL_SET)
{
std::string assocCellSetName;
diy::load(bb, assocCellSetName);
diy::load(bb, data);
field =
vtkm::cont::Field(name, assoc, assocCellSetName, vtkm::cont::DynamicArrayHandle(data));
}
else if (assoc == vtkm::cont::Field::Association::LOGICAL_DIM)
{
vtkm::IdComponent assocLogicalDim;
diy::load(bb, assocLogicalDim);
diy::load(bb, data);
field = vtkm::cont::Field(name, assoc, assocLogicalDim, vtkm::cont::DynamicArrayHandle(data));
}
else
{
diy::load(bb, data);
field = vtkm::cont::Field(name, assoc, vtkm::cont::DynamicArrayHandle(data));
}
}
};
} // diy
#endif //vtk_m_cont_Field_h
......@@ -89,5 +89,6 @@ vtkm_unit_tests(SOURCES ${unit_tests})
set(mpi_unit_tests
UnitTestFieldRangeGlobalCompute.cxx
UnitTestSerializationArrayHandle.cxx
UnitTestSerializationDataSet.cxx
)
vtkm_unit_tests(MPI SOURCES ${mpi_unit_tests})
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/TestingSerialization.h>
using namespace vtkm::cont::testing::serialization;
namespace
{
struct TestEqualCellSet
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
void operator()(
const vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>& cs1,
const vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>& cs2) const
{
vtkm::TopologyElementTagPoint p2cFrom{};
vtkm::TopologyElementTagCell p2cTo{};
VTKM_TEST_ASSERT(cs1.GetName() == cs2.GetName(), "cellset names don't match");
VTKM_TEST_ASSERT(cs1.GetNumberOfPoints() == cs2.GetNumberOfPoints(),
"cellset number of points don't match");
TestEqualArrayHandle{}(cs1.GetShapesArray(p2cFrom, p2cTo), cs2.GetShapesArray(p2cFrom, p2cTo));
TestEqualArrayHandle{}(cs1.GetNumIndicesArray(p2cFrom, p2cTo),
cs2.GetNumIndicesArray(p2cFrom, p2cTo));
TestEqualArrayHandle{}(cs1.GetConnectivityArray(p2cFrom, p2cTo),
cs2.GetConnectivityArray(p2cFrom, p2cTo));
TestEqualArrayHandle{}(cs1.GetIndexOffsetArray(p2cFrom, p2cTo),
cs2.GetIndexOffsetArray(p2cFrom, p2cTo));
}
template <vtkm::IdComponent DIMENSION>
void operator()(const vtkm::cont::CellSetStructured<DIMENSION>& cs1,
const vtkm::cont::CellSetStructured<DIMENSION>& cs2) const
{
VTKM_TEST_ASSERT(cs1.GetName() == cs2.GetName(), "cellset names don't match");
VTKM_TEST_ASSERT(cs1.GetPointDimensions() == cs2.GetPointDimensions(),
"CellSetStructured: point dimensions don't match");
}
template <typename CellSetTypes>
void operator()(const vtkm::cont::DynamicCellSetBase<CellSetTypes>& cs1,
const vtkm::cont::DynamicCellSetBase<CellSetTypes>& cs2)
{
cs1.CastAndCall(*this, cs2);
}
template <typename CellSet, typename CellSetTypes>
void operator()(const CellSet& cs, const vtkm::cont::DynamicCellSetBase<CellSetTypes>& dcs)
{
this->operator()(cs, dcs.template Cast<CellSet>());
}
};
template <typename FieldTypeList, typename FieldStorageList, typename CellSetTypes>
void TestEqualDataSet(
const vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypes>& s1,
const vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypes>& s2)
{
const auto& ds1 = s1.DataSet;
const auto& ds2 = s2.DataSet;
VTKM_TEST_ASSERT(ds1.GetNumberOfCoordinateSystems() == ds2.GetNumberOfCoordinateSystems(),
"datasets' number of coordinate systems don't match");
for (vtkm::IdComponent i = 0; i < ds1.GetNumberOfCoordinateSystems(); ++i)
{
TestEqualArrayHandle{}(ds1.GetCoordinateSystem(i).GetData(),
ds2.GetCoordinateSystem(i).GetData());
}
VTKM_TEST_ASSERT(ds1.GetNumberOfCellSets() == ds2.GetNumberOfCellSets(),
"datasets' number of cellsets don't match");
for (vtkm::IdComponent i = 0; i < ds1.GetNumberOfCellSets(); ++i)
{
TestEqualCellSet{}(ds1.GetCellSet(i).ResetCellSetList(CellSetTypes{}),
ds2.GetCellSet(i).ResetCellSetList(CellSetTypes{}));
}
VTKM_TEST_ASSERT(ds1.GetNumberOfFields() == ds2.GetNumberOfFields(),
"datasets' number of fields don't match");
for (vtkm::IdComponent i = 0; i < ds1.GetNumberOfFields(); ++i)
{
auto f1 = ds1.GetField(i);
auto f2 = ds2.GetField(i);
VTKM_TEST_ASSERT(f1.GetName() == f2.GetName(), "field names don't match");
VTKM_TEST_ASSERT(f1.GetAssociation() == f1.GetAssociation(), "fields' association don't match");
if (f1.GetAssociation() == vtkm::cont::Field::Association::CELL_SET)
{
VTKM_TEST_ASSERT(f1.GetAssocCellSet() == f2.GetAssocCellSet(),
"fields' associated cellset names don't match");
}
else if (f1.GetAssociation() == vtkm::cont::Field::Association::LOGICAL_DIM)
{
VTKM_TEST_ASSERT(f1.GetAssocLogicalDim() == f2.GetAssocLogicalDim(),
"fields' associated logical dims don't match");
}
TestEqualArrayHandle{}(
f1.GetData().ResetTypeAndStorageLists(FieldTypeList{}, FieldStorageList{}),
f2.GetData().ResetTypeAndStorageLists(FieldTypeList{}, FieldStorageList{}));
}
}
void RunTest(const vtkm::cont::DataSet& ds)
{
using TypeList = vtkm::ListTagBase<vtkm::Float32>;
using StorageList = VTKM_DEFAULT_STORAGE_LIST_TAG;
using CellSetTypes = vtkm::ListTagBase<vtkm::cont::CellSetExplicit<>,
vtkm::cont::CellSetSingleType<>,
vtkm::cont::CellSetStructured<1>,
vtkm::cont::CellSetStructured<2>,
vtkm::cont::CellSetStructured<3>>;
TestSerialization(vtkm::cont::SerializableDataSet<TypeList, StorageList, CellSetTypes>(ds),
TestEqualDataSet<TypeList, StorageList, CellSetTypes>);
}
void TestDataSetSerialization()
{
vtkm::cont::testing::MakeTestDataSet makeDS;
std::cout << "Testing 1D Uniform DataSet #0\n";
RunTest(makeDS.Make1DUniformDataSet0());
std::cout << "Testing 1D Uniform DataSet #1\n";
RunTest(makeDS.Make1DUniformDataSet1());
std::cout << "Testing 2D Uniform DataSet #0\n";
RunTest(makeDS.Make2DUniformDataSet0());