ATLAS Offline Software
Loading...
Searching...
No Matches
DefaultMerger.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include <exception>
8#include <iostream>
9
10namespace H5Utils {
11
13 hsize_t mergeAxis,
14 int chunkSize,
15 bool requireSameFormat,
16 std::size_t bufferSize,
17 bool bufferInRows) :
18 m_mergeAxis(mergeAxis),
19 m_chunkSize(chunkSize),
20 m_requireSameFormat(requireSameFormat),
21 m_bufferSize(bufferSize),
22 m_measureBufferInRows(bufferInRows) {}
23
25
27 H5::Group& target,
28 const H5::Group& source)
29 {
30 // Check if this group was empty before we started
31 bool isEmpty = target.getNumObjs() == 0;
32
33 // Iterate through each child of the source group
34 for (hsize_t ii = 0; ii < source.getNumObjs(); ++ii) {
35 H5G_obj_t childType = source.getObjTypeByIdx(ii);
36 std::string childName = source.getObjnameByIdx(ii);
37 // Find the correct index in the target
38 hsize_t targetIdx = 0;
39 for (; targetIdx < target.getNumObjs(); ++targetIdx)
40 if (target.getObjnameByIdx(targetIdx) == childName)
41 break;
42 bool found = targetIdx != target.getNumObjs();
43 if (found) {
44 // Make sure these are the same type!
45 if (target.getObjTypeByIdx(targetIdx) != childType)
46 throw std::invalid_argument(
47 "Both target and source contain " + childName +
48 " but they have different types!");
49 }
50 else if (m_requireSameFormat && !isEmpty) {
51 throw std::invalid_argument(
52 "Target and source have different formats!");
53 }
54 switch (childType) {
55 case H5G_GROUP:
56 {
57 H5::Group sg = source.openGroup(childName);
58 H5::Group tg = found ?
59 target.openGroup(childName) :
60 createFrom(target, sg);
61 try {
62 merge(tg, sg);
63 }
64 catch (...) {
65 std::cerr << "Encountered an error merging child " << childName << std::endl;
66 throw;
67 }
68 }
69 break;
70 case H5G_DATASET:
71 {
72 H5::DataSet sd = source.openDataSet(childName);
73 if (sd.getSpace().getSimpleExtentNdims() == 0) {
74 std::cerr << "WARNING: skipping scalar '"
75 << childName << "'" << std::endl;
76 break;
77 }
78 H5::DataSet td = found ?
79 target.openDataSet(childName) :
80 createFrom(target, sd);
81 try {
82 merge(td, sd);
83 }
84 catch (...) {
85 std::cerr << "Encountered an error merging child " << childName << std::endl;
86 throw;
87 }
88 }
89 break;
90 default:
91 break;
92 }
93 } //> end loop over children
94 // TODO - this did no check to see if target contained something source
95 // didn't, this is probably fine though.
96 } //> end function merge(group)
97
99 H5::DataSet& target,
100 const H5::DataSet& source)
101 {
102 std::size_t bufferSize = m_bufferSize;
104 // Need to calculate the actual buffer size
105 std::size_t rowSize = getRowSize(source, m_mergeAxis);
106 if (std::size_t(-1) / m_bufferSize < rowSize)
107 std::overflow_error("Requested buffer would overflow the register!");
108 bufferSize = rowSize * m_bufferSize;
109 }
110 mergeDatasets(target, source, m_mergeAxis, bufferSize);
111 }
112
114 H5::H5Location& targetLocation,
115 const H5::DataSet& source)
116 {
117 return createDataSet(targetLocation, source, m_mergeAxis, m_chunkSize);
118 }
119} //> end namespace H5Utils
hsize_t m_mergeAxis
The axis to merge along.
H5::DataSet createFrom(H5::H5Location &targetLocation, const H5::DataSet &source) override
Make a new dataset from information in a source dataset.
int m_chunkSize
The chunk size to apply.
DefaultMerger(hsize_t mergeAxis=0, int chunkSize=-1, bool requireSameFormat=true, std::size_t bufferSize=-1, bool bufferInRows=false)
Create the merger.
std::size_t m_bufferSize
The size of the buffer.
bool m_measureBufferInRows
Whether to measure the buffer in bytes or rows.
void merge(H5::Group &target, const H5::Group &source) override
Merge a source group into a target group.
bool m_requireSameFormat
Whether to require the same group structure.
HDF5 Tuple Writer.
Definition common.h:20
std::size_t getRowSize(const H5::DataSet &ds, hsize_t axis)
Calculate the size of a row of a dataset in bytes.
H5::DataSet createDataSet(H5::H5Location &targetLocation, const H5::DataSet &source, hsize_t mergeAxis, int chunkSize=-1, int mergeExtent=-1)
Make a new dataset using the properties of another.
void mergeDatasets(H5::DataSet &target, const H5::DataSet &source, hsize_t mergeAxis, std::size_t bufferSize=-1)
Merge two datasets.
Definition merge.py:1