2 #ifndef OPENGM_GRAPHICALMODEL_HDF5_HXX
3 #define OPENGM_GRAPHICALMODEL_HDF5_HXX
32 struct IsValidTypeForHdf5Save {
33 typedef opengm::meta::Bool<
35 opengm::meta::IsInvalidType<T>::value
38 typedef opengm::meta::Bool<
39 std::numeric_limits<T>::is_specialized
42 value=meta::And<tmpBoolAType::value,tmpBoolBType::value>::value
46 struct StoredValueTypeInfo{
55 template<
class GM,
size_t IX,
size_t DX,
bool END>
56 struct GetFunctionRegistration;
58 template<
class GM,
size_t IX,
size_t DX>
59 struct GetFunctionRegistration<GM, IX, DX, false> {
60 static size_t get(
const size_t functionIndex) {
61 if(IX == functionIndex) {
62 typedef typename meta::TypeAtTypeList<typename GM::FunctionTypeList, IX>::type TypeAtIX ;
63 return FunctionRegistration< TypeAtIX >::Id;
66 return GetFunctionRegistration
69 meta::Increment<IX>::value,
71 meta::EqualNumber<meta::Increment<IX>::value, DX>::value
72 >::get(functionIndex);
77 template<
class GM,
size_t IX,
size_t DX>
78 struct GetFunctionRegistration<GM, IX, DX, true>{
79 static size_t get(
const size_t functionIndex) {
80 throw RuntimeError(
"Incorrect function type id.");
84 template<
class GM,
size_t IX,
size_t DX,
bool END>
85 struct SaveAndLoadFunctions;
87 template<
class GM,
size_t IX,
size_t DX>
88 struct SaveAndLoadFunctions<GM, IX, DX, false>
90 template<
class HDF5_HANDLE>
97 if(meta::FieldAccess::template byIndex<IX>(gm.functionDataField_).functionData_.functions_.size() != 0)
100 std::stringstream ss;
101 typedef typename meta::TypeAtTypeList<typename GM::FunctionTypeList, IX>::type TypeAtIX;
102 ss <<
"function-id-" << (FunctionRegistration<TypeAtIX>::Id);
106 size_t indexCounter = 0;
107 size_t valueCounter = 0;
108 for(
size_t i=0; i<meta::FieldAccess::template byIndex<IX>(gm.functionDataField_).functionData_.functions_.size(); ++i) {
109 indexCounter += FunctionSerialization<TypeAtIX>::indexSequenceSize(
110 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
111 valueCounter += FunctionSerialization<TypeAtIX>::valueSequenceSize(
112 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
118 for(
size_t i=0; i<meta::FieldAccess::template byIndex<IX>(gm.functionDataField_).functionData_.functions_.size(); ++i) {
119 FunctionSerialization<TypeAtIX>::serialize(
120 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i], indexIter, valueIter);
121 indexIter+=FunctionSerialization<TypeAtIX>::indexSequenceSize(
122 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
123 valueIter+=FunctionSerialization<TypeAtIX>::valueSequenceSize(
124 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
129 if(storeValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsFloat)) {
130 typedef opengm::detail_types::Float StorageType;
131 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
139 else if(storeValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsDouble)) {
140 typedef opengm::detail_types::Double StorageType;
141 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
149 else if(storeValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsUInt)) {
151 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
159 else if (storeValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsInt)) {
161 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
173 typedef typename opengm::meta::Increment<IX>::type NewIX;
174 SaveAndLoadFunctions<GM, NewIX::value, DX, opengm::meta::EqualNumber<NewIX::value, DX>::value >
::save(handle, gm,storeValueTypeAs);
177 template<
class HDF5_HANDLE>
182 const std::vector<opengm::UInt64Type>& numberOfFunctions,
183 const std::vector<opengm::UInt64Type>& functionIndexLookup,
184 const std::vector<bool> & useFunction,
188 if(useFunction[IX]==
true) {
190 bool foundIndex=
false;
191 for(
size_t i=0;i<functionIndexLookup.size();++i) {
192 if(functionIndexLookup[i]==IX ) {
199 throw RuntimeError(
"Could not load function.");
202 if(numberOfFunctions[mappedIndex] != 0) {
204 std::stringstream ss;
205 typedef typename meta::TypeAtTypeList<typename GM::FunctionTypeList, IX>::type TypeAtIX ;
206 ss <<
"function-id-" << (FunctionRegistration<TypeAtIX>::Id);
211 std::string subDatasetName(
"indices");
215 std::string subDatasetName(
"values");
218 if(oldFormat==
false) {
219 if(loadValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsFloat)) {
220 typedef opengm::detail_types::Float StorageType;
221 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
227 serializationValues=tmpSerializationValues;
230 else if(loadValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsDouble)) {
231 typedef opengm::detail_types::Double StorageType;
232 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
238 serializationValues=tmpSerializationValues;
241 else if(loadValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsUInt)) {
243 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
249 serializationValues=tmpSerializationValues;
252 else if (loadValueTypeAs==static_cast<opengm::UInt64Type>(StoredValueTypeInfo::AsInt)) {
254 if(opengm::meta::Compare<GmValueType,StorageType>::value==
true) {
260 serializationValues=tmpSerializationValues;
270 gm.template functions<IX>().resize(numberOfFunctions[mappedIndex]);
274 for(
size_t i=0; i<meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_.size(); ++i) {
275 FunctionSerialization<TypeAtIX>::deserialize(
276 indexIter, valueIter, meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
277 indexIter += FunctionSerialization<TypeAtIX>::indexSequenceSize(
278 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
279 valueIter+=FunctionSerialization<TypeAtIX>::valueSequenceSize(
280 meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[i]);
287 typedef typename opengm::meta::Increment<IX>::type NewIX;
288 SaveAndLoadFunctions<GM, NewIX::value, DX, opengm::meta::EqualNumber<NewIX::value, DX>::value >
::load
289 (handle, gm, numberOfFunctions,functionIndexLookup,useFunction,loadValueTypeAs,oldFormat);
293 template<
class GM,
size_t IX,
size_t DX>
294 struct SaveAndLoadFunctions<GM, IX, DX, true> {
295 template<
class HDF5_HANDLE>
306 template<
class HDF5_HANDLE>
311 const std::vector<opengm::UInt64Type>& numberOfFunctions,
312 const std::vector<opengm::UInt64Type>& functionIndexLookup,
313 const std::vector<bool> & useFunction ,
331 const std::string& filepath,
332 const std::string& datasetName
335 typedef typename GM::ValueType ValueType;
336 typedef typename GM::FactorType FactorType;
338 if(IsValidTypeForHdf5Save<typename GM::ValueType>::value==
false) {
343 std::vector<UInt64Type> serializationIndicies;
346 if(opengm::meta::Compare<opengm::detail_types::Float,ValueType>::value==
true) {
350 else if(opengm::meta::Compare<opengm::detail_types::Double,ValueType>::value==
true) {
354 else if(opengm::meta::Compare<opengm::detail_types::LongDouble,ValueType>::value==
true) {
355 throw RuntimeError(std::string(
"ValueType \" long double\" has no support for hdf5 export"));
358 else if(opengm::meta::Compare<opengm::detail_types::Bool,ValueType>::value==
true) {
362 else if(std::numeric_limits<ValueType>::is_integer==
true && std::numeric_limits<ValueType>::is_signed==
false) {
366 else if(std::numeric_limits<ValueType>::is_integer==
true && std::numeric_limits<ValueType>::is_signed==
true) {
370 throw RuntimeError(std::string(
"ValueType has no support for hdf5 export"));
375 std::string subDatasetName(
"header");
378 serializationIndicies.push_back(gm.numberOfVariables());
379 serializationIndicies.push_back(gm.factors_.size());
380 serializationIndicies.push_back(GM::NrOfFunctionTypes);
381 for(
size_t i=0; i<GM::NrOfFunctionTypes; ++i) {
382 const size_t fRegId=GetFunctionRegistration
386 GM::NrOfFunctionTypes,
387 meta::EqualNumber<GM::NrOfFunctionTypes, 0>::value
389 serializationIndicies.push_back(fRegId);
390 serializationIndicies.push_back(gm.numberOfFunctions(i));
392 serializationIndicies.push_back(storeValueTypeAs);
398 std::string subDatasetName(
"numbers-of-states");
399 serializationIndicies.resize(gm.numberOfVariables());
400 for(
size_t i=0;i<gm.numberOfVariables();++i) {
401 serializationIndicies[i]=
406 serializationIndicies.clear();
413 std::string subDatasetName(
"factors");
414 for(
size_t i = 0; i < gm.factors_.size(); ++i) {
415 serializationIndicies.push_back(static_cast<opengm::UInt64Type>(gm.factors_[i].functionIndex_));
416 serializationIndicies.push_back(static_cast<opengm::UInt64Type>(gm.factors_[i].functionTypeId_));
417 serializationIndicies.push_back(static_cast<opengm::UInt64Type>(gm.factors_[i].numberOfVariables()));
418 for(
size_t j = 0; j < gm.factors_[i].numberOfVariables(); ++j) {
420 serializationIndicies.push_back(static_cast<opengm::UInt64Type> (gm.factors_[i].variableIndex(j)));
423 if(serializationIndicies.size() != 0)
marray::hdf5::save(group, subDatasetName, serializationIndicies);
433 const std::string& filepath,
434 const std::string& datasetName
437 typedef typename GM::ValueType ValueType;
438 typedef typename GM::FactorType FactorType;
442 std::vector<opengm::UInt64Type> numberOfFunctions;
443 std::vector<opengm::UInt64Type> functionIndexLookup;
444 std::vector<bool> useFunction(GM::NrOfFunctionTypes,
false);
447 bool oldFormat=
false;
450 std::string subDatasetName(
"header");
455 if(!(serializationIndicies.
size() > 5 && serializationIndicies.
size() <= 5 + 2 * GM::NrOfFunctionTypes)) {
457 if(serializationIndicies[0] != 2 || serializationIndicies[1] != 0) {
458 throw RuntimeError(
"This version of the HDF5 file format is not supported by this version of OpenGM.");
462 gm.factors_.resize(serializationIndicies[3], FactorType(&gm));
463 numberOfFunctions.resize(serializationIndicies[4]);
464 functionIndexLookup.resize(serializationIndicies[4]);
465 typeRegisterId.
resize(serializationIndicies[4]);
466 for(
size_t i=0; i<numberOfFunctions.size(); ++i) {
468 typeRegisterId[i]=serializationIndicies[5 + 2 * i];
469 numberOfFunctions[i]=serializationIndicies[5 + 2*i + 1];
472 if(serializationIndicies.
size()!=5+2*numberOfFunctions.size()+1) {
473 if(serializationIndicies.
size()==5+2*numberOfFunctions.size()) {
481 loadValueTypeAs=serializationIndicies[serializationIndicies.
size()-1];
486 for(
size_t i=0; i<numberOfFunctions.size(); ++i) {
489 for(
size_t j=0; j<GM::NrOfFunctionTypes; ++j) {
490 opengm::UInt64Type regIdInList=GetFunctionRegistration<GM, 0, GM::NrOfFunctionTypes, meta::EqualNumber<GM::NrOfFunctionTypes, 0>::value>::get(j);
491 if(regIdToFind==regIdInList ) {
493 functionIndexLookup[i]=j;
498 if(foundId==
false && numberOfFunctions[i]!=0) {
499 std::stringstream ss;
500 ss <<
"The HDF5 file contains the function type "
502 <<
" which is not contained in the type list in the C++ code.";
508 std::string subDatasetName(
"numbers-of-states");
510 gm.space_.assignDense(serializationIndicies.
begin(), serializationIndicies.
end());
514 (group, gm, numberOfFunctions,functionIndexLookup,useFunction,loadValueTypeAs,oldFormat);
516 gm.factorsVis_.clear();
518 if(gm.factors_.size() != 0) {
520 std::string subDatasetName(
"factors");
523 for(
size_t i = 0; i < gm.factors_.size(); ++i) {
524 gm.factors_[i].functionIndex_ =
static_cast<opengm::UInt64Type> (serializationIndicies[sIndex]);
526 gm.factors_[i].functionTypeId_ =
535 gm.factors_[i].vis_.assign(gm.factorsVis_,indexInVisVector,order);
536 gm.order_ = std::max( static_cast<size_t>(gm.order_),
537 static_cast<size_t>(order));
543 for(
size_t j = 0; j < gm.factors_[i].numberOfVariables(); ++j) {
544 gm.factorsVis_.push_back( static_cast<opengm::UInt64Type> (serializationIndicies[sIndex]));
555 gm.variableFactorAdjaceny_.resize(gm.numberOfVariables());
558 for(
size_t i=0; i<gm.numberOfFactors(); ++i) {
559 for(
size_t vi=0;vi<gm[i].numberOfVariables(); ++vi) {
560 gm.variableFactorAdjaceny_[ gm[i].variableIndex(vi) ].insert(i);
571 #endif // #ifndef OPENGM_GRAPHICALMODEL_HDF5_HXX
hid_t createFile(const std::string &, HDF5Version=DEFAULT_HDF5_VERSION)
Create an HDF5 file.
STL-compliant random access iterator for View and Marray.
void load(GM_ &gm, const std::string &, const std::string &)
detail_types::Int64Type Int64Type
int32
hid_t createGroup(const hid_t &, const std::string &)
Create an HDF5 group.
#define OPENGM_ASSERT(expression)
void load(const hid_t &, const std::string &, Marray< T > &)
Load an Marray from an HDF5 dataset.
const unsigned int VERSION_MAJOR
major version number of opengm
detail_types::UInt64Type UInt64Type
uint64
const size_t size() const
void closeFile(const hid_t &)
Close an HDF5 file.
void save(const hid_t &, const std::string &, const Marray< T > &)
Save an Marray as an HDF5 dataset.
#define OPENGM_CHECK_OP(A, OP, B, TXT)
void resize(const size_t, const T &=T())
Resize (existing entries are preserved, new entries are initialized).
void closeGroup(const hid_t &)
Close an HDF5 group.
const unsigned int VERSION_MINOR
minor version number of opengm
void save(const GM &, const std::string &, const std::string &)
save a graphical model to an HDF5 file
hid_t openFile(const std::string &, FileAccessMode=READ_ONLY, HDF5Version=DEFAULT_HDF5_VERSION)
Open an HDF5 file.
hid_t openGroup(const hid_t &, const std::string &)
Open an HDF5 group.