@@ -283,6 +283,7 @@ void RecordComponent::flush(
283283 dCreate.extent = getExtent ();
284284 dCreate.dtype = getDatatype ();
285285 dCreate.options = rc.m_dataset .value ().options ;
286+ dCreate.joinedDimension = joinedDimension ();
286287 IOHandler ()->enqueue (IOTask (this , dCreate));
287288 }
288289 }
@@ -419,6 +420,21 @@ bool RecordComponent::dirtyRecursive() const
419420
420421void RecordComponent::storeChunk (
421422 auxiliary::WriteBuffer buffer, Datatype dtype, Offset o, Extent e)
423+ {
424+ verifyChunk (dtype, o, e);
425+
426+ Parameter<Operation::WRITE_DATASET> dWrite;
427+ dWrite.offset = o;
428+ dWrite.extent = e;
429+ dWrite.dtype = dtype;
430+ /* std::static_pointer_cast correctly reference-counts the pointer */
431+ dWrite.data = std::move (buffer);
432+ auto &rc = get ();
433+ rc.m_chunks .push (IOTask (this , std::move (dWrite)));
434+ }
435+
436+ void RecordComponent::verifyChunk (
437+ Datatype dtype, Offset const &o, Extent const &e) const
422438{
423439 if (constant ())
424440 throw std::runtime_error (
@@ -434,31 +450,58 @@ void RecordComponent::storeChunk(
434450 throw std::runtime_error (oss.str ());
435451 }
436452 uint8_t dim = getDimensionality ();
437- if (e.size () != dim || o.size () != dim)
438- {
439- std::ostringstream oss;
440- oss << " Dimensionality of chunk ("
441- << " offset=" << o.size () << " D, "
442- << " extent=" << e.size () << " D) "
443- << " and record component (" << int (dim) << " D) "
444- << " do not match." ;
445- throw std::runtime_error (oss.str ());
446- }
447453 Extent dse = getExtent ();
448- for (uint8_t i = 0 ; i < dim; ++i)
449- if (dse[i] < o[i] + e[i])
450- throw std::runtime_error (
451- " Chunk does not reside inside dataset (Dimension on index " +
452- std::to_string (i) + " . DS: " + std::to_string (dse[i]) +
453- " - Chunk: " + std::to_string (o[i] + e[i]) + " )" );
454454
455- Parameter<Operation::WRITE_DATASET> dWrite;
456- dWrite.offset = o;
457- dWrite.extent = e;
458- dWrite.dtype = dtype;
459- /* std::static_pointer_cast correctly reference-counts the pointer */
460- dWrite.data = std::move (buffer);
461- auto &rc = get ();
462- rc.m_chunks .push (IOTask (this , std::move (dWrite)));
455+ if (auto jd = joinedDimension (); jd.has_value ())
456+ {
457+ if (o.size () != 0 )
458+ {
459+ std::ostringstream oss;
460+ oss << " Joined array: Must specify an empty offset (given: "
461+ << " offset=" << o.size () << " D, "
462+ << " extent=" << e.size () << " D)." ;
463+ throw std::runtime_error (oss.str ());
464+ }
465+ if (e.size () != dim)
466+ {
467+ std::ostringstream oss;
468+ oss << " Joined array: Dimensionalities of chunk extent and dataset "
469+ " extent must be equivalent (given: "
470+ << " offset=" << o.size () << " D, "
471+ << " extent=" << e.size () << " D)." ;
472+ throw std::runtime_error (oss.str ());
473+ }
474+ for (size_t i = 0 ; i < dim; ++i)
475+ {
476+ if (i != jd.value () && e[i] != dse[i])
477+ {
478+ throw std::runtime_error (
479+ " Joined array: Chunk extent on non-joined dimensions must "
480+ " be equivalent to dataset extents (Dimension on index " +
481+ std::to_string (i) + " . DS: " + std::to_string (dse[i]) +
482+ " - Chunk: " + std::to_string (o[i] + e[i]) + " )" );
483+ }
484+ }
485+ }
486+ else
487+ {
488+ if (e.size () != dim || o.size () != dim)
489+ {
490+ std::ostringstream oss;
491+ oss << " Dimensionality of chunk ("
492+ << " offset=" << o.size () << " D, "
493+ << " extent=" << e.size () << " D) "
494+ << " and record component (" << int (dim) << " D) "
495+ << " do not match." ;
496+ throw std::runtime_error (oss.str ());
497+ }
498+ for (uint8_t i = 0 ; i < dim; ++i)
499+ if (dse[i] < o[i] + e[i])
500+ throw std::runtime_error (
501+ " Chunk does not reside inside dataset (Dimension on "
502+ " index " +
503+ std::to_string (i) + " . DS: " + std::to_string (dse[i]) +
504+ " - Chunk: " + std::to_string (o[i] + e[i]) + " )" );
505+ }
463506}
464507} // namespace openPMD
0 commit comments