@@ -271,6 +271,7 @@ void RecordComponent::flush(
271271 dCreate.extent = getExtent ();
272272 dCreate.dtype = getDatatype ();
273273 dCreate.options = rc.m_dataset .value ().options ;
274+ dCreate.joinedDimension = joinedDimension ();
274275 IOHandler ()->enqueue (IOTask (this , dCreate));
275276 }
276277 }
@@ -407,6 +408,21 @@ bool RecordComponent::dirtyRecursive() const
407408
408409void RecordComponent::storeChunk (
409410 auxiliary::WriteBuffer buffer, Datatype dtype, Offset o, Extent e)
411+ {
412+ verifyChunk (dtype, o, e);
413+
414+ Parameter<Operation::WRITE_DATASET> dWrite;
415+ dWrite.offset = o;
416+ dWrite.extent = e;
417+ dWrite.dtype = dtype;
418+ /* std::static_pointer_cast correctly reference-counts the pointer */
419+ dWrite.data = std::move (buffer);
420+ auto &rc = get ();
421+ rc.m_chunks .push (IOTask (this , std::move (dWrite)));
422+ }
423+
424+ void RecordComponent::verifyChunk (
425+ Datatype dtype, Offset const &o, Extent const &e) const
410426{
411427 if (constant ())
412428 throw std::runtime_error (
@@ -422,31 +438,58 @@ void RecordComponent::storeChunk(
422438 throw std::runtime_error (oss.str ());
423439 }
424440 uint8_t dim = getDimensionality ();
425- if (e.size () != dim || o.size () != dim)
426- {
427- std::ostringstream oss;
428- oss << " Dimensionality of chunk ("
429- << " offset=" << o.size () << " D, "
430- << " extent=" << e.size () << " D) "
431- << " and record component (" << int (dim) << " D) "
432- << " do not match." ;
433- throw std::runtime_error (oss.str ());
434- }
435441 Extent dse = getExtent ();
436- for (uint8_t i = 0 ; i < dim; ++i)
437- if (dse[i] < o[i] + e[i])
438- throw std::runtime_error (
439- " Chunk does not reside inside dataset (Dimension on index " +
440- std::to_string (i) + " . DS: " + std::to_string (dse[i]) +
441- " - Chunk: " + std::to_string (o[i] + e[i]) + " )" );
442442
443- Parameter<Operation::WRITE_DATASET> dWrite;
444- dWrite.offset = o;
445- dWrite.extent = e;
446- dWrite.dtype = dtype;
447- /* std::static_pointer_cast correctly reference-counts the pointer */
448- dWrite.data = std::move (buffer);
449- auto &rc = get ();
450- rc.m_chunks .push (IOTask (this , std::move (dWrite)));
443+ if (auto jd = joinedDimension (); jd.has_value ())
444+ {
445+ if (o.size () != 0 )
446+ {
447+ std::ostringstream oss;
448+ oss << " Joined array: Must specify an empty offset (given: "
449+ << " offset=" << o.size () << " D, "
450+ << " extent=" << e.size () << " D)." ;
451+ throw std::runtime_error (oss.str ());
452+ }
453+ if (e.size () != dim)
454+ {
455+ std::ostringstream oss;
456+ oss << " Joined array: Dimensionalities of chunk extent and dataset "
457+ " extent must be equivalent (given: "
458+ << " offset=" << o.size () << " D, "
459+ << " extent=" << e.size () << " D)." ;
460+ throw std::runtime_error (oss.str ());
461+ }
462+ for (size_t i = 0 ; i < dim; ++i)
463+ {
464+ if (i != jd.value () && e[i] != dse[i])
465+ {
466+ throw std::runtime_error (
467+ " Joined array: Chunk extent on non-joined dimensions must "
468+ " be equivalent to dataset extents (Dimension on index " +
469+ std::to_string (i) + " . DS: " + std::to_string (dse[i]) +
470+ " - Chunk: " + std::to_string (o[i] + e[i]) + " )" );
471+ }
472+ }
473+ }
474+ else
475+ {
476+ if (e.size () != dim || o.size () != dim)
477+ {
478+ std::ostringstream oss;
479+ oss << " Dimensionality of chunk ("
480+ << " offset=" << o.size () << " D, "
481+ << " extent=" << e.size () << " D) "
482+ << " and record component (" << int (dim) << " D) "
483+ << " do not match." ;
484+ throw std::runtime_error (oss.str ());
485+ }
486+ for (uint8_t i = 0 ; i < dim; ++i)
487+ if (dse[i] < o[i] + e[i])
488+ throw std::runtime_error (
489+ " Chunk does not reside inside dataset (Dimension on "
490+ " index " +
491+ std::to_string (i) + " . DS: " + std::to_string (dse[i]) +
492+ " - Chunk: " + std::to_string (o[i] + e[i]) + " )" );
493+ }
451494}
452495} // namespace openPMD
0 commit comments