Skip to content

Commit

Permalink
Allow users to provide buffer creation functors
Browse files Browse the repository at this point in the history
  • Loading branch information
franzpoeschel committed Feb 2, 2021
1 parent 99457b6 commit 92e29da
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions include/openPMD/RecordComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,20 +246,38 @@ class RecordComponent : public BaseRecordComponent
* a new buffer.
*
* Data can be written into the returned buffer until the next call to
* Series::flush().
* The precise consumption time is backend-defined, but not before the next
* call to Series::flush() and not after ending the current step in
* step-based mode.
* Series::flush() at which time the data will be read from.
*
* In order to provide a view into backend buffers, this call must possibly
* create files and datasets in the backend, making it MPI-collective.
* In order to avoid this, calling Series::flush() prior to this is
* recommended to flush definitions.
*
* @param createBuffer If the backend in use as no special support for this
* operation, the openPMD API will fall back to creating a buffer,
* queuing it for writing and returning a view into that buffer to
* the user. The functor createBuffer will be called for this
* purpose. It consumes a length parameter of type size_t and should
* return a shared_ptr of type T to a buffer at least that length.
*
* @return View into a buffer that can be filled with data.
*/
template< typename T, typename F >
Span< T > storeChunk( Offset, Extent, F && createBuffer );

/**
* Overload of span-based storeChunk() that uses operator new() to create
* a buffer.
*/
template< typename T >
Span< T > storeChunk( Offset, Extent );
Span< T > storeChunk( Offset offset, Extent extent )
{
return storeChunk< T >(
std::move( offset ), std::move( extent ), []( size_t size ) {
return std::shared_ptr< T >{
new T[ size ], []( auto * ptr ) { delete[] ptr; } };
} );
}

static constexpr char const * const SCALAR = "\vScalar";

Expand Down Expand Up @@ -515,14 +533,16 @@ RecordComponent::storeChunk(T_ContiguousContainer & data, Offset o, Extent e)
storeChunk(shareRaw(data), offset, extent);
}

template< typename T >
template< typename T, typename F >
inline Span< T >
RecordComponent::storeChunk( Offset o, Extent e )
RecordComponent::storeChunk( Offset o, Extent e, F && createBuffer )
{
if( constant() )
throw std::runtime_error("Chunks cannot be written for a constant RecordComponent.");
throw std::runtime_error(
"Chunks cannot be written for a constant RecordComponent." );
if( empty() )
throw std::runtime_error("Chunks cannot be written for an empty RecordComponent.");
throw std::runtime_error(
"Chunks cannot be written for an empty RecordComponent." );
Datatype dtype = determineDatatype<T>();
if( dtype != getDatatype() )
{
Expand Down Expand Up @@ -591,8 +611,7 @@ RecordComponent::storeChunk( Offset o, Extent e )
auto &out = *getBufferView.out;
if( !out.taskSupportedByBackend )
{
std::shared_ptr< T > data{
new T[ size ], []( auto *ptr ) { delete[] ptr; } };
auto data = std::forward< F >( createBuffer )( size );
out.ptr = static_cast< void * >( data.get() );
storeChunk( std::move( data ), std::move( o ), std::move( e ) );
}
Expand Down

0 comments on commit 92e29da

Please sign in to comment.