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;
116 template<
typename T >
127 template<
typename T >
156 template<
typename T >
157 std::shared_ptr< T > loadChunk(
160 double targetUnitSI = std::numeric_limits< double >::quiet_NaN() );
171 template<
typename T >
173 std::shared_ptr< T >,
176 double targetUnitSI = std::numeric_limits< double >::quiet_NaN() );
178 template<
typename T >
179 void storeChunk(std::shared_ptr< T >, Offset, Extent);
181 template<
typename T_ContiguousContainer >
182 typename std::enable_if<
185 storeChunk(T_ContiguousContainer &, Offset = {0u}, Extent = {-1u});
187 static constexpr
char const *
const SCALAR =
"\vScalar";
196 std::shared_ptr< std::queue< IOTask > > m_chunks;
197 std::shared_ptr< Attribute > m_constantValue;
198 std::shared_ptr< bool > m_isEmpty = std::make_shared< bool >( false );
201 void flush(std::string
const&);
221 dirtyRecursive()
const;
227 std::shared_ptr< bool > hasBeenRead = std::make_shared< bool >( false );
231 template<
typename T >
236 throw std::runtime_error(
"A recordComponent can not (yet) be made constant after it has been written.");
239 *m_isConstant =
true;
243 template<
typename T >
248 determineDatatype< T >(),
249 Extent( dimensions, 0 ) ) );
252 template<
typename T >
253 inline std::shared_ptr< T >
256 uint8_t dim = getDimensionality();
261 if( o.size() == 1u && o.at(0) == 0u && dim > 1u )
262 offset = Offset(dim, 0u);
265 Extent extent(dim, 1u);
266 if( e.size() == 1u && e.at(0) == -1u )
268 extent = getExtent();
269 for( uint8_t i = 0u; i < dim; ++i )
270 extent[i] -= offset[i];
275 uint64_t numPoints = 1u;
276 for(
auto const& dimensionSize : extent )
277 numPoints *= dimensionSize;
279 auto newData = std::shared_ptr<T>(
new T[numPoints], []( T *p ){
delete [] p; });
280 loadChunk(newData, offset, extent, targetUnitSI);
284 template<
typename T >
288 if( !std::isnan(targetUnitSI) )
289 throw std::runtime_error(
"unitSI scaling during chunk loading not yet implemented");
290 Datatype dtype = determineDatatype(data);
291 if( dtype != getDatatype() )
292 if( !isSameInteger< T >( dtype ) &&
293 !isSameFloatingPoint< T >( dtype ) &&
294 !isSameComplexFloatingPoint< T >( dtype ) )
295 throw std::runtime_error(
"Type conversion during chunk loading not yet implemented");
297 uint8_t dim = getDimensionality();
302 if( o.size() == 1u && o.at(0) == 0u && dim > 1u )
303 offset = Offset(dim, 0u);
306 Extent extent(dim, 1u);
307 if( e.size() == 1u && e.at(0) == -1u )
309 extent = getExtent();
310 for( uint8_t i = 0u; i < dim; ++i )
311 extent[i] -= offset[i];
316 if( extent.size() != dim || offset.size() != dim )
318 std::ostringstream oss;
319 oss <<
"Dimensionality of chunk (" 320 <<
"offset=" << offset.size() <<
"D, " 321 <<
"extent=" << extent.size() <<
"D) " 322 <<
"and record component (" 325 throw std::runtime_error(oss.str());
327 Extent dse = getExtent();
328 for( uint8_t i = 0; i < dim; ++i )
329 if( dse[i] < offset[i] + extent[i] )
330 throw std::runtime_error(
"Chunk does not reside inside dataset (Dimension on index " + std::to_string(i)
331 +
". DS: " + std::to_string(dse[i])
332 +
" - Chunk: " + std::to_string(offset[i] + extent[i])
335 throw std::runtime_error(
"Unallocated pointer passed during chunk loading.");
339 uint64_t numPoints = 1u;
340 for(
auto const& dimensionSize : extent )
341 numPoints *= dimensionSize;
343 T value = m_constantValue->get<
T >();
345 T* raw_ptr = data.get();
346 std::fill(raw_ptr, raw_ptr + numPoints, value);
350 dRead.offset = offset;
351 dRead.extent = extent;
352 dRead.dtype = getDatatype();
353 dRead.data = std::static_pointer_cast<
void >(data);
354 m_chunks->push(
IOTask(
this, dRead));
358 template<
typename T >
360 RecordComponent::storeChunk(std::shared_ptr<T> data, Offset o, Extent e)
363 throw std::runtime_error(
"Chunks cannot be written for a constant RecordComponent.");
365 throw std::runtime_error(
"Chunks cannot be written for an empty RecordComponent.");
367 throw std::runtime_error(
"Unallocated pointer passed during chunk store.");
368 Datatype dtype = determineDatatype(data);
369 if( dtype != getDatatype() )
371 std::ostringstream oss;
372 oss <<
"Datatypes of chunk data (" 374 <<
") and record component (" 376 <<
") do not match.";
377 throw std::runtime_error(oss.str());
379 uint8_t dim = getDimensionality();
380 if( e.size() != dim || o.size() != dim )
382 std::ostringstream oss;
383 oss <<
"Dimensionality of chunk (" 384 <<
"offset=" << o.size() <<
"D, " 385 <<
"extent=" << e.size() <<
"D) " 386 <<
"and record component (" 389 throw std::runtime_error(oss.str());
391 Extent dse = getExtent();
392 for( uint8_t i = 0; i < dim; ++i )
393 if( dse[i] < o[i] + e[i] )
394 throw std::runtime_error(
"Chunk does not reside inside dataset (Dimension on index " + std::to_string(i)
395 +
". DS: " + std::to_string(dse[i])
396 +
" - Chunk: " + std::to_string(o[i] + e[i])
402 dWrite.dtype = dtype;
404 dWrite.data = std::static_pointer_cast<
void const >(data);
405 m_chunks->push(
IOTask(
this, dWrite));
408 template<
typename T_ContiguousContainer >
409 inline typename std::enable_if<
412 RecordComponent::storeChunk(T_ContiguousContainer & data, Offset o, Extent e)
414 uint8_t dim = getDimensionality();
419 if( o.size() == 1u && o.at(0) == 0u && dim > 1u )
420 offset = Offset(dim, 0u);
423 Extent extent(dim, 1u);
426 if( e.size() == 1u && e.at(0) == -1u && dim == 1u )
427 extent.at(0) = data.size();
431 storeChunk(
shareRaw(data), offset, extent);
Definition: Dataset.hpp:36
Self-contained description of a single IO operation.
Definition: IOTask.hpp:550
RecordComponent & makeEmpty(uint8_t dimensions)
Create a dataset with zero extent in each dimension.
Definition: RecordComponent.hpp:245
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:38
Emulate in the C++17 concept ContiguousContainer.
Definition: RecordComponent.hpp:57
RecordComponent & makeConstant(T)
Create a dataset with regular extent and constant value.
Definition: RecordComponent.hpp:233
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:42
Varidic datatype supporting at least all formats for attributes specified in the openPMD standard...
Definition: Attribute.hpp:50
Definition: RecordComponent.hpp:78
Public definitions of openPMD-api.
Definition: Date.cpp:29
Definition: Record.hpp:33
Definition: IOTask.hpp:365
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:254
Definition: IOTask.hpp:336
Definition: BaseRecordComponent.hpp:34