openPMD-api
PatchRecordComponent.hpp
1 /* Copyright 2017-2021 Fabian Koller
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 #pragma once
22 
23 #include "openPMD/backend/BaseRecordComponent.hpp"
24 
25 #include <sstream>
26 #include <stdexcept>
27 #include <string>
28 #include <unordered_map>
29 
30 // expose private and protected members for invasive testing
31 #ifndef OPENPMD_private
32 #define OPENPMD_private private
33 #endif
34 
35 namespace openPMD
36 {
37 
42 {
43  template <typename T, typename T_key, typename T_container>
44  friend class Container;
45 
46  template <typename>
47  friend class BaseRecord;
48  friend class ParticlePatches;
49  friend class PatchRecord;
50 
51 public:
52  PatchRecordComponent &setUnitSI(double);
53 
54  PatchRecordComponent &resetDataset(Dataset);
55 
56  uint8_t getDimensionality() const;
57  Extent getExtent() const;
58 
59  template <typename T>
60  std::shared_ptr<T> load();
61  template <typename T>
62  void load(std::shared_ptr<T>);
63  template <typename T>
64  void store(uint64_t idx, T);
65 
66  OPENPMD_private:
68 
69  void flush(std::string const &, internal::FlushParams const &);
70  void read();
71 
72  std::shared_ptr<std::queue<IOTask> > m_chunks;
73 
82  bool dirtyRecursive() const;
83 }; // PatchRecordComponent
84 
85 template <typename T>
86 inline std::shared_ptr<T> PatchRecordComponent::load()
87 {
88  uint64_t numPoints = getExtent()[0];
89  auto newData =
90  std::shared_ptr<T>(new T[numPoints], [](T *p) { delete[] p; });
91  load(newData);
92  return newData;
93 }
94 
95 template <typename T>
96 inline void PatchRecordComponent::load(std::shared_ptr<T> data)
97 {
98  Datatype dtype = determineDatatype<T>();
99  if (dtype != getDatatype())
100  throw std::runtime_error(
101  "Type conversion during particle patch loading not yet "
102  "implemented");
103 
104  if (!data)
105  throw std::runtime_error(
106  "Unallocated pointer passed during ParticlePatch loading.");
107 
108  uint64_t numPoints = getExtent()[0];
109 
111 
113  dRead.offset = {0};
114  dRead.extent = {numPoints};
115  dRead.dtype = getDatatype();
116  dRead.data = std::static_pointer_cast<void>(data);
117  m_chunks->push(IOTask(this, dRead));
118 }
119 
120 template <typename T>
121 inline void PatchRecordComponent::store(uint64_t idx, T data)
122 {
123  Datatype dtype = determineDatatype<T>();
124  if (dtype != getDatatype())
125  {
126  std::ostringstream oss;
127  oss << "Datatypes of patch data (" << dtype << ") and dataset ("
128  << getDatatype() << ") do not match.";
129  throw std::runtime_error(oss.str());
130  }
131 
132  Extent dse = getExtent();
133  if (dse[0] - 1u < idx)
134  throw std::runtime_error(
135  "Index does not reside inside patch (no. patches: " +
136  std::to_string(dse[0]) + " - index: " + std::to_string(idx) + ")");
137 
139  dWrite.offset = {idx};
140  dWrite.extent = {1};
141  dWrite.dtype = dtype;
142  dWrite.data = std::make_shared<T>(data);
143  m_chunks->push(IOTask(this, dWrite));
144 }
145 } // namespace openPMD
Definition: ParticlePatches.hpp:31
Definition: Dataset.hpp:35
Self-contained description of a single IO operation.
Definition: IOTask.hpp:615
Definition: PatchRecord.hpp:31
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:45
Public definitions of openPMD-api.
Definition: Date.cpp:28
Definition: BaseRecord.hpp:35
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition: AbstractIOHandler.hpp:103
Definition: PatchRecordComponent.hpp:41
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:105
Definition: BaseRecordComponent.hpp:33