openPMD-api
 
Loading...
Searching...
No Matches
RecordComponent.hpp
1/* Copyright 2017-2021 Fabian Koller, Axel Huebl and Franz Poeschel
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/Dataset.hpp"
24#include "openPMD/Datatype.hpp"
25#include "openPMD/auxiliary/ShareRaw.hpp"
26#include "openPMD/auxiliary/TypeTraits.hpp"
27#include "openPMD/auxiliary/UniquePtr.hpp"
28#include "openPMD/backend/Attributable.hpp"
29#include "openPMD/backend/BaseRecordComponent.hpp"
30
31// comment to prevent this include from being moved by clang-format
32#include "openPMD/DatatypeMacros.hpp"
33
34#include <array>
35#include <cmath>
36#include <limits>
37#include <memory>
38#include <queue>
39#include <sstream>
40#include <stdexcept>
41#include <string>
42#include <type_traits>
43#include <utility>
44#include <variant>
45#include <vector>
46
47// expose private and protected members for invasive testing
48#ifndef OPENPMD_protected
49#define OPENPMD_protected protected:
50#endif
51
52namespace openPMD
53{
54
55template <typename T>
57
58class RecordComponent;
59
60namespace internal
61{
62 class RecordComponentData : public BaseRecordComponentData
63 {
64 public:
65 RecordComponentData();
66
67 RecordComponentData(RecordComponentData const &) = delete;
68 RecordComponentData(RecordComponentData &&) = delete;
69
70 RecordComponentData &operator=(RecordComponentData const &) = delete;
71 RecordComponentData &operator=(RecordComponentData &&) = delete;
72
76 std::queue<IOTask> m_chunks;
77
78 void push_chunk(IOTask &&task);
90 bool m_isEmpty = false;
95 bool m_hasBeenExtended = false;
96
97 void reset() override
98 {
99 BaseRecordComponentData::reset();
100 m_chunks = std::queue<IOTask>();
101 m_constantValue = -1;
102 m_isEmpty = false;
103 m_hasBeenExtended = false;
104 }
105 };
106 template <typename, typename>
107 class BaseRecordData;
108} // namespace internal
109
110template <typename>
111class BaseRecord;
112
113class RecordComponent : public BaseRecordComponent
114{
115 template <typename T, typename T_key, typename T_container>
116 friend class Container;
117 friend class Iteration;
118 friend class ParticleSpecies;
119 template <typename>
120 friend class BaseRecord;
121 template <typename, typename>
122 friend class internal::BaseRecordData;
123 friend class Record;
124 friend class Mesh;
125 template <typename>
126 friend class DynamicMemoryView;
128 friend class MeshRecordComponent;
129 template <typename T>
130 friend T &internal::makeOwning(T &self, Series);
131
132public:
133 enum class Allocation
134 {
135 USER,
136 API,
137 AUTO
138 }; // Allocation
139
147 RecordComponent(BaseRecord<RecordComponent> const &);
148
149 RecordComponent &setUnitSI(double);
150
172
173 uint8_t getDimensionality() const;
174 Extent getExtent() const;
175
184 template <typename T>
186
195 template <typename T>
196 RecordComponent &makeEmpty(uint8_t dimensions);
197
206 RecordComponent &makeEmpty(Datatype dt, uint8_t dimensions);
207
215 bool empty() const;
216
224 template <typename T>
225 std::shared_ptr<T> loadChunk(Offset = {0u}, Extent = {-1u});
226
227#define OPENPMD_ENUMERATE_TYPES(type) , std::shared_ptr<type>
228 using shared_ptr_dataset_types = auxiliary::detail::variant_tail_t<
229 auxiliary::detail::bottom OPENPMD_FOREACH_DATASET_DATATYPE(
230 OPENPMD_ENUMERATE_TYPES)>;
231#undef OPENPMD_ENUMERATE_TYPES
232
243 shared_ptr_dataset_types loadChunkVariant(Offset = {0u}, Extent = {-1u});
244
266 template <typename T>
267 void loadChunk(std::shared_ptr<T> data, Offset offset, Extent extent);
268
285 template <typename T>
286 void loadChunk(std::shared_ptr<T[]> data, Offset offset, Extent extent);
287
303 template <typename T>
304 void loadChunkRaw(T *data, Offset offset, Extent extent);
305
324 template <typename T>
325 void storeChunk(std::shared_ptr<T> data, Offset offset, Extent extent);
326
336 template <typename T>
337 void storeChunk(std::shared_ptr<T[]> data, Offset offset, Extent extent);
338
351 template <typename T>
352 void storeChunk(UniquePtrWithLambda<T> data, Offset offset, Extent extent);
353
366 template <typename T, typename Del>
367 void storeChunk(std::unique_ptr<T, Del> data, Offset offset, Extent extent);
368
381 template <typename T>
382 void storeChunkRaw(T const *data, Offset offset, Extent extent);
383
399 template <typename T_ContiguousContainer>
400 typename std::enable_if_t<
401 auxiliary::IsContiguousContainer_v<T_ContiguousContainer>>
403 T_ContiguousContainer &data,
404 Offset offset = {0u},
405 Extent extent = {-1u});
406
440 template <typename T, typename F>
441 DynamicMemoryView<T>
442 storeChunk(Offset offset, Extent extent, F &&createBuffer);
443
448 template <typename T>
449 DynamicMemoryView<T> storeChunk(Offset, Extent);
450
481 template <typename Visitor, typename... Args>
482 auto visit(Args &&...args) -> decltype(Visitor::template call<char>(
483 std::declval<RecordComponent &>(), std::forward<Args>(args)...));
484
485 static constexpr char const *const SCALAR = "\vScalar";
486
487protected:
488 void flush(std::string const &, internal::FlushParams const &);
489 void read(bool require_unit_si);
490
491private:
499
500 void storeChunk(
501 auxiliary::WriteBuffer buffer, Datatype datatype, Offset o, Extent e);
502
503 // clang-format off
504OPENPMD_protected
505 // clang-format on
506
507 using Data_t = internal::RecordComponentData;
508 std::shared_ptr<Data_t> m_recordComponentData;
509
512
513 inline Data_t const &get() const
514 {
515 // cannot call this in the const overload
516 // datasetDefined(*m_recordComponentData);
517 return *m_recordComponentData;
518 }
519
520 inline Data_t &get()
521 {
522 setDatasetDefined(*m_recordComponentData);
523 return *m_recordComponentData;
524 }
525
526 inline std::shared_ptr<Data_t> getShared()
527 {
528 return m_recordComponentData;
529 }
530
531 inline void setData(std::shared_ptr<internal::RecordComponentData> data)
532 {
533 m_recordComponentData = std::move(data);
534 BaseRecordComponent::setData(m_recordComponentData);
535 }
536
537 void readBase(bool require_unit_si);
538
539 template <typename T>
540 void verifyChunk(Offset const &, Extent const &) const;
541
542 void verifyChunk(Datatype, Offset const &, Extent const &) const;
543}; // RecordComponent
544
545namespace internal
546{
547 // Must put this after the definition of RecordComponent due to the
548 // deque<RecordComponent>
549 struct HomogenizeExtents
550 {
551 std::deque<RecordComponent> without_extent;
552 std::optional<Extent> retrieved_extent;
553 bool verify_homogeneous_extents = true;
554
555 explicit HomogenizeExtents();
556 HomogenizeExtents(bool verify_homogeneous_extents);
557
558 void check_extent(Attributable const &callsite, RecordComponent &);
559 auto merge(Attributable const &callsite, HomogenizeExtents)
560 -> HomogenizeExtents &;
561 void homogenize(Attributable const &callsite) &&;
562 };
563} // namespace internal
564
565} // namespace openPMD
566
567#include "openPMD/UndefDatatypeMacros.hpp"
568// comment to prevent these includes from being moved by clang-format
569#include "RecordComponent.tpp"
Layer to manage storage of attributes associated with file objects.
Definition Attributable.hpp:222
Definition Attribute.hpp:64
Definition Dataset.hpp:38
A view into a buffer that might be reallocated at some points and thus has changing base pointers ove...
Definition Span.hpp:97
Self-contained description of a single IO operation.
Definition IOTask.hpp:836
Definition RecordComponent.hpp:114
DynamicMemoryView< T > storeChunk(Offset offset, Extent extent, F &&createBuffer)
Overload of storeChunk() that lets the openPMD API allocate a buffer.
RecordComponent & makeEmpty(uint8_t dimensions)
Create a dataset with zero extent in each dimension.
Definition RecordComponent.cpp:748
RecordComponent & resetDataset(Dataset)
Declare the dataset's type and extent.
Definition RecordComponent.cpp:206
auto visit(Args &&...args) -> decltype(Visitor::template call< char >(std::declval< RecordComponent & >(), std::forward< Args >(args)...))
Run a template functor on the type of the record component, similar to std::visit().
bool empty() const
Returns true if this is an empty record component.
Definition RecordComponent.cpp:369
RecordComponent(BaseRecord< RecordComponent > const &)
Avoid object slicing when using a Record as a scalar Record Component.
Definition RecordComponent.cpp:190
std::shared_ptr< T > loadChunk(Offset={0u}, Extent={-1u})
Load and allocate a chunk of data.
Definition RecordComponent.cpp:754
void storeChunk(std::shared_ptr< T > data, Offset offset, Extent extent)
Store a chunk of data from a chunk of memory.
Definition RecordComponent.cpp:937
RecordComponent & makeConstant(T)
Create a dataset with regular extent and constant value.
Definition RecordComponent.cpp:733
std::enable_if_t< auxiliary::IsContiguousContainer_v< T_ContiguousContainer > > storeChunk(T_ContiguousContainer &data, Offset offset={0u}, Extent extent={-1u})
Store a chunk of data from a contiguous container.
shared_ptr_dataset_types loadChunkVariant(Offset={0u}, Extent={-1u})
std::variant-based version of allocating loadChunk<T>(Offset, Extent)
Definition RecordComponent.cpp:726
void storeChunk(std::unique_ptr< T, Del > data, Offset offset, Extent extent)
Store a chunk of data from a chunk of memory, unique pointer version.
void storeChunkRaw(T const *data, Offset offset, Extent extent)
Store a chunk of data from a chunk of memory, raw pointer version.
Definition RecordComponent.cpp:978
void loadChunkRaw(T *data, Offset offset, Extent extent)
Load a chunk of data into pre-allocated memory, raw pointer version.
Definition RecordComponent.cpp:931
Implementation for the root level of the openPMD hierarchy.
Definition Series.hpp:288
Unique Pointer class that uses a dynamic destructor type.
Definition UniquePtr.hpp:86
Definition BaseRecord.hpp:52
Definition RecordComponent.hpp:63
bool m_hasBeenExtended
User has extended the dataset, but the EXTEND task must yet be flushed to the backend.
Definition RecordComponent.hpp:95
std::queue< IOTask > m_chunks
Chunk reading/writing requests on the contained dataset.
Definition RecordComponent.hpp:76
Attribute m_constantValue
Stores the value for constant record components.
Definition RecordComponent.hpp:83
bool m_isEmpty
True if this component is an empty dataset, i.e.
Definition RecordComponent.hpp:90
Public definitions of openPMD-api.
Definition Date.cpp:29
@ T
time
Definition UnitDimension.hpp:41
Datatype
Concrete datatype of an object available at runtime.
Definition Datatype.hpp:51
Definition Attributable.hpp:251
Definition Memory.hpp:48
Definition TypeTraits.hpp:200
Parameters recursively passed through the openPMD hierarchy when flushing.
Definition AbstractIOHandler.hpp:106