ATLAS Offline Software
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 
6 #include "HDF5Utils/MergeUtils.h"
7 #include <exception>
8 #include <iostream>
9 
10 namespace 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 
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) :
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;
103  if (m_measureBufferInRows) {
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
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
H5Utils::DefaultMerger::m_mergeAxis
hsize_t m_mergeAxis
The axis to merge along.
Definition: DefaultMerger.h:73
H5Utils::DefaultMerger::DefaultMerger
DefaultMerger(hsize_t mergeAxis=0, int chunkSize=-1, bool requireSameFormat=true, std::size_t bufferSize=-1, bool bufferInRows=false)
Create the merger.
Definition: DefaultMerger.cxx:12
H5Utils::DefaultMerger::m_chunkSize
int m_chunkSize
The chunk size to apply.
Definition: DefaultMerger.h:75
AthExHiveOpts.chunkSize
chunkSize
Definition: AthExHiveOpts.py:101
H5Utils::DefaultMerger::m_bufferSize
std::size_t m_bufferSize
The size of the buffer.
Definition: DefaultMerger.h:79
python.selector.AtlRunQuerySelectorLhcOlc.sd
sd
Definition: AtlRunQuerySelectorLhcOlc.py:612
DefaultMerger.h
H5Utils::DefaultMerger::merge
void merge(H5::Group &target, const H5::Group &source) override
Merge a source group into a target group.
Definition: DefaultMerger.cxx:26
H5Utils::DefaultMerger::m_requireSameFormat
bool m_requireSameFormat
Whether to require the same group structure.
Definition: DefaultMerger.h:77
H5Utils::DefaultMerger::~DefaultMerger
~DefaultMerger()
Definition: DefaultMerger.cxx:24
H5Utils
HDF5 Tuple Writer.
Definition: common.h:20
H5Utils::DefaultMerger::m_measureBufferInRows
bool m_measureBufferInRows
Whether to measure the buffer in bytes or rows.
Definition: DefaultMerger.h:81
MergeUtils.h
H5Utils::getRowSize
std::size_t getRowSize(const H5::DataSet &ds, hsize_t axis)
Calculate the size of a row of a dataset in bytes.
Definition: MergeUtils.cxx:254
H5Utils::mergeDatasets
void mergeDatasets(H5::DataSet &target, const H5::DataSet &source, hsize_t mergeAxis, std::size_t bufferSize=-1)
Merge two datasets.
Definition: MergeUtils.cxx:130
H5Utils::DefaultMerger::createFrom
H5::DataSet createFrom(H5::H5Location &targetLocation, const H5::DataSet &source) override
Make a new dataset from information in a source dataset.
Definition: DefaultMerger.cxx:113
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
copySelective.target
string target
Definition: copySelective.py:37
H5Utils::createDataSet
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.
Definition: MergeUtils.cxx:222
copySelective.source
string source
Definition: copySelective.py:32