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 <unordered_map>
26 #include <string>
27 #include <sstream>
28 #include <stdexcept>
29 
30 // expose private and protected members for invasive testing
31 #ifndef OPENPMD_private
32 # define OPENPMD_private private
33 #endif
34 
35 
36 namespace openPMD
37 {
38 
43 {
44  template<
45  typename T,
46  typename T_key,
47  typename T_container
48  >
49  friend
50  class Container;
51 
52  template< typename > friend class BaseRecord;
53  friend class ParticlePatches;
54  friend class PatchRecord;
55 
56 public:
57  PatchRecordComponent& setUnitSI(double);
58 
59  PatchRecordComponent& resetDataset(Dataset);
60 
61  uint8_t getDimensionality() const;
62  Extent getExtent() const;
63 
64  template< typename T >
65  std::shared_ptr< T > load();
66  template< typename T >
67  void load(std::shared_ptr< T >);
68  template< typename T >
69  void store(uint64_t idx, T);
70 
71 OPENPMD_private:
73 
74  void flush(std::string const&);
75  void read();
76 
77  std::shared_ptr< std::queue< IOTask > > m_chunks;
78 
87  bool
88  dirtyRecursive() const;
89 }; // PatchRecordComponent
90 
91 template< typename T >
92 inline std::shared_ptr< T >
93 PatchRecordComponent::load()
94 {
95  uint64_t numPoints = getExtent()[0];
96  auto newData = std::shared_ptr< T >(new T[numPoints], []( T *p ){ delete [] p; });
97  load(newData);
98  return newData;
99 }
100 
101 template< typename T >
102 inline void
103 PatchRecordComponent::load(std::shared_ptr< T > data)
104 {
105  Datatype dtype = determineDatatype< T >();
106  if( dtype != getDatatype() )
107  throw std::runtime_error("Type conversion during particle patch loading not yet implemented");
108 
109  if( !data )
110  throw std::runtime_error("Unallocated pointer passed during ParticlePatch loading.");
111 
112  uint64_t numPoints = getExtent()[0];
113 
115 
117  dRead.offset = {0};
118  dRead.extent = {numPoints};
119  dRead.dtype = getDatatype();
120  dRead.data = std::static_pointer_cast< void >(data);
121  m_chunks->push(IOTask(this, dRead));
122 }
123 
124 template< typename T >
125 inline void
126 PatchRecordComponent::store(uint64_t idx, T data)
127 {
128  Datatype dtype = determineDatatype< T >();
129  if( dtype != getDatatype() )
130  {
131  std::ostringstream oss;
132  oss << "Datatypes of patch data ("
133  << dtype
134  << ") and dataset ("
135  << getDatatype()
136  << ") do not match.";
137  throw std::runtime_error(oss.str());
138  }
139 
140  Extent dse = getExtent();
141  if( dse[0] - 1u < idx )
142  throw std::runtime_error("Index does not reside inside patch (no. patches: " + std::to_string(dse[0])
143  + " - index: " + std::to_string(idx) + ")");
144 
145  Parameter< Operation::WRITE_DATASET > dWrite;
146  dWrite.offset = {idx};
147  dWrite.extent = {1};
148  dWrite.dtype = dtype;
149  dWrite.data = std::make_shared< T >(data);
150  m_chunks->push(IOTask(this, dWrite));
151 }
152 } // namespace openPMD
openPMD::Datatype
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:45
openPMD::BaseRecord
Definition: BaseRecord.hpp:36
openPMD::Parameter< Operation::READ_DATASET >
Definition: IOTask.hpp:373
openPMD::PatchRecord
Definition: PatchRecord.hpp:32
openPMD::UnitDimension::T
@ T
time
openPMD::ParticlePatches
Definition: ParticlePatches.hpp:32
openPMD
Public definitions of openPMD-api.
Definition: Date.cpp:29
openPMD::Container
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:106
openPMD::IOTask
Self-contained description of a single IO operation.
Definition: IOTask.hpp:589
openPMD::BaseRecordComponent
Definition: BaseRecordComponent.hpp:34
openPMD::Dataset
Definition: Dataset.hpp:36
openPMD::PatchRecordComponent
Definition: PatchRecordComponent.hpp:42