23 #include "openPMD/backend/BaseRecordComponent.hpp" 24 #include "openPMD/auxiliary/ShareRaw.hpp" 25 #include "openPMD/Dataset.hpp" 34 #include <type_traits> 39 #ifndef OPENPMD_protected 40 # define OPENPMD_protected protected 56 template<
typename T >
59 static constexpr
bool value =
false;
62 template<
typename T_Value >
65 static constexpr
bool value =
true;
74 static constexpr
bool value =
true;
88 template<
typename T_elem >
105 uint8_t getDimensionality()
const;
106 Extent getExtent()
const;
108 template<
typename T >
119 template<
typename T >
129 template<
typename T >
130 std::shared_ptr< T > loadChunk(
133 double targetUnitSI = std::numeric_limits< double >::quiet_NaN() );
144 template<
typename T >
146 std::shared_ptr< T >,
149 double targetUnitSI = std::numeric_limits< double >::quiet_NaN() );
151 template<
typename T >
152 void storeChunk(std::shared_ptr< T >, Offset, Extent);
154 template<
typename T_ContiguousContainer >
155 typename std::enable_if<
158 storeChunk(T_ContiguousContainer &, Offset = {0u}, Extent = {-1u});
160 static constexpr
char const *
const SCALAR =
"\vScalar";
169 std::shared_ptr< std::queue< IOTask > > m_chunks;
170 std::shared_ptr< Attribute > m_constantValue;
171 std::shared_ptr< bool > m_isEmpty = std::make_shared< bool >( false );
174 void flush(std::string
const&);
187 template<
typename T >
189 RecordComponent::makeConstant(
T value)
192 throw std::runtime_error(
"A recordComponent can not (yet) be made constant after it has been written.");
195 *m_isConstant =
true;
199 template<
typename T >
204 determineDatatype< T >(),
205 Extent( dimensions, 0 ) ) );
208 template<
typename T >
209 inline std::shared_ptr< T >
212 uint8_t dim = getDimensionality();
217 if( o.size() == 1u && o.at(0) == 0u && dim > 1u )
218 offset = Offset(dim, 0u);
221 Extent extent(dim, 1u);
222 if( e.size() == 1u && e.at(0) == -1u )
224 extent = getExtent();
225 for( uint8_t i = 0u; i < dim; ++i )
226 extent[i] -= offset[i];
231 uint64_t numPoints = 1u;
232 for(
auto const& dimensionSize : extent )
233 numPoints *= dimensionSize;
235 auto newData = std::shared_ptr<T>(
new T[numPoints], []( T *p ){
delete [] p; });
236 loadChunk(newData, offset, extent, targetUnitSI);
240 template<
typename T >
244 if( !std::isnan(targetUnitSI) )
245 throw std::runtime_error(
"unitSI scaling during chunk loading not yet implemented");
246 Datatype dtype = determineDatatype(data);
247 if( dtype != getDatatype() )
248 if( !isSameInteger< T >( dtype ) && !isSameFloatingPoint< T >( dtype ) )
249 throw std::runtime_error(
"Type conversion during chunk loading not yet implemented");
251 uint8_t dim = getDimensionality();
256 if( o.size() == 1u && o.at(0) == 0u && dim > 1u )
257 offset = Offset(dim, 0u);
260 Extent extent(dim, 1u);
261 if( e.size() == 1u && e.at(0) == -1u )
263 extent = getExtent();
264 for( uint8_t i = 0u; i < dim; ++i )
265 extent[i] -= offset[i];
270 if( extent.size() != dim || offset.size() != dim )
272 std::ostringstream oss;
273 oss <<
"Dimensionality of chunk (" 274 <<
"offset=" << offset.size() <<
"D, " 275 <<
"extent=" << extent.size() <<
"D) " 276 <<
"and record component (" 279 throw std::runtime_error(oss.str());
281 Extent dse = getExtent();
282 for( uint8_t i = 0; i < dim; ++i )
283 if( dse[i] < offset[i] + extent[i] )
284 throw std::runtime_error(
"Chunk does not reside inside dataset (Dimension on index " + std::to_string(i)
285 +
" - DS: " + std::to_string(dse[i])
286 +
" - Chunk: " + std::to_string(offset[i] + extent[i])
289 throw std::runtime_error(
"Unallocated pointer passed during chunk loading.");
293 uint64_t numPoints = 1u;
294 for(
auto const& dimensionSize : extent )
295 numPoints *= dimensionSize;
297 T value = m_constantValue->get<
T >();
299 T* raw_ptr = data.get();
300 std::fill(raw_ptr, raw_ptr + numPoints, value);
304 dRead.offset = offset;
305 dRead.extent = extent;
306 dRead.dtype = getDatatype();
307 dRead.data = std::static_pointer_cast<
void >(data);
308 m_chunks->push(
IOTask(
this, dRead));
312 template<
typename T >
314 RecordComponent::storeChunk(std::shared_ptr<T> data, Offset o, Extent e)
317 throw std::runtime_error(
"Chunks cannot be written for a constant RecordComponent.");
319 throw std::runtime_error(
"Chunks cannot be written for an empty RecordComponent.");
321 throw std::runtime_error(
"Unallocated pointer passed during chunk store.");
322 Datatype dtype = determineDatatype(data);
323 if( dtype != getDatatype() )
325 std::ostringstream oss;
326 oss <<
"Datatypes of chunk data (" 328 <<
") and record component (" 330 <<
") do not match.";
331 throw std::runtime_error(oss.str());
333 uint8_t dim = getDimensionality();
334 if( e.size() != dim || o.size() != dim )
336 std::ostringstream oss;
337 oss <<
"Dimensionality of chunk (" 338 <<
"offset=" << o.size() <<
"D, " 339 <<
"extent=" << e.size() <<
"D) " 340 <<
"and record component (" 343 throw std::runtime_error(oss.str());
345 Extent dse = getExtent();
346 for( uint8_t i = 0; i < dim; ++i )
347 if( dse[i] < o[i] + e[i] )
348 throw std::runtime_error(
"Chunk does not reside inside dataset (Dimension on index " + std::to_string(i)
349 +
" - DS: " + std::to_string(dse[i])
350 +
" - Chunk: " + std::to_string(o[i] + e[i])
356 dWrite.dtype = dtype;
358 dWrite.data = std::static_pointer_cast<
void const >(data);
359 m_chunks->push(
IOTask(
this, dWrite));
362 template<
typename T_ContiguousContainer >
363 inline typename std::enable_if<
366 RecordComponent::storeChunk(T_ContiguousContainer & data, Offset o, Extent e)
368 uint8_t dim = getDimensionality();
373 if( o.size() == 1u && o.at(0) == 0u && dim > 1u )
374 offset = Offset(dim, 0u);
377 Extent extent(dim, 1u);
380 if( e.size() == 1u && e.at(0) == -1u && dim == 1u )
381 extent.at(0) = data.size();
385 storeChunk(
shareRaw(data), offset, extent);
Definition: Dataset.hpp:36
Self-contained description of a single IO operation.
Definition: IOTask.hpp:468
RecordComponent & makeEmpty(uint8_t dimensions)
Create a dataset with zero extent in each dimension.
Definition: RecordComponent.hpp:201
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:35
Emulate in the C++17 concept ContiguousContainer.
Definition: RecordComponent.hpp:57
std::shared_ptr< T > shareRaw(T *x)
Share ownership with a raw pointer.
Definition: ShareRaw.hpp:47
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:38
Varidic datatype supporting at least all formats for attributes specified in the openPMD standard...
Definition: Attribute.hpp:49
Definition: RecordComponent.hpp:78
Public definitions of openPMD-api.
Definition: Date.cpp:28
Definition: Record.hpp:33
Definition: IOTask.hpp:332
Definition: BaseRecord.hpp:36
Definition: ParticleSpecies.hpp:34
Container for N-dimensional, homogeneous Records.
Definition: Mesh.hpp:39
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:70
std::shared_ptr< T > loadChunk(Offset={0u}, Extent={-1u}, double targetUnitSI=std::numeric_limits< double >::quiet_NaN())
Load and allocate a chunk of data.
Definition: RecordComponent.hpp:210
Definition: IOTask.hpp:303
Definition: BaseRecordComponent.hpp:34