19 #ifndef GEOSX_DATAREPOSITORY_WRAPPERHELPERS_HPP_ 20 #define GEOSX_DATAREPOSITORY_WRAPPERHELPERS_HPP_ 24 #define RESTART_TYPE_LOGGING 0 27 #include "BufferOps.hpp" 28 #include "BufferOpsDevice.hpp" 33 #include "codingUtilities/traits.hpp" 36 #include <conduit.hpp> 41 #if RESTART_TYPE_LOGGING 42 #include <unordered_set> 47 namespace dataRepository
49 namespace wrapperHelpers
56 #if RESTART_TYPE_LOGGING 57 static std::unordered_set< std::string > m_types;
59 if( !m_types.count( typeString ) )
61 m_types.insert( typeString );
70 template<
typename T,
typename ... INDICES >
71 std::string getIndicesToComponent( T
const &,
int const component, INDICES
const ... existingIndices )
77 template<
typename ... INDICES >
78 std::string getIndicesToComponent(
R1Tensor const &,
int const component, INDICES
const ... existingIndices )
81 template<
typename T >
82 T
const * getPointerToComponent( T
const & var,
int const component )
89 real64 const * getPointerToComponent(
R1Tensor const & var,
int const component )
92 return &var[ component ];
99 template<
typename T >
100 inline std::enable_if_t< traits::HasMemberFunction_size< T >,
localIndex >
101 size( T
const & value )
102 {
return LvArray::integerConversion< localIndex >( value.size() ); }
104 template<
typename T >
105 inline std::enable_if_t< !traits::HasMemberFunction_size< T >,
localIndex >
112 {
return const_cast< char *
>( var.data() ); }
115 dataPtr( Path & var )
116 {
return const_cast< char *
>( var.data() ); }
118 template<
typename T >
119 inline std::enable_if_t< traits::HasMemberFunction_data< T >,
typename traits::Pointer< T > >
121 {
return value.data(); }
123 template<
typename T >
124 inline std::enable_if_t< !traits::HasMemberFunction_data< T >,
typename traits::Pointer< T > >
129 inline typename traits::ConstPointer< T >
130 dataPtr( T
const & value )
131 {
return dataPtr( const_cast< T & >( value ) ); }
134 template<
typename T >
135 inline std::enable_if_t< traits::HasMemberFunction_resize< T > >
137 { value.resize( newSize ); }
139 template<
typename T >
140 inline std::enable_if_t< !traits::HasMemberFunction_resize< T > >
146 template<
typename T,
int NDIM,
typename PERMUTATION >
147 inline std::enable_if_t< DefaultValue< Array< T, NDIM, PERMUTATION > >::has_default_value >
148 resizeDefault( Array< T, NDIM, PERMUTATION > & value,
150 DefaultValue< Array< T, NDIM, PERMUTATION > >
const & defaultValue )
151 { value.resizeDefault( newSize, defaultValue.value ); }
153 template<
typename T >
156 { resize( value, newSize ); }
159 template<
typename T,
int NDIM,
typename PERMUTATION >
161 resizeDimensions( Array< T, NDIM, PERMUTATION > & value,
int num_dims,
localIndex const *
const dims )
162 { value.resize( num_dims, dims ); }
164 template<
typename T >
166 resizeDimensions( T & value,
int num_dims,
localIndex const *
const dims )
173 resize( value, dims[ 0 ] );
177 template<
typename T >
180 {
return sizeof( *dataPtr( std::declval< T >() ) ); }
183 template<
typename T >
185 byteSize( T
const & value )
186 {
return size( value ) * byteSizeOfElement< T >(); }
189 template<
typename T >
191 numElementsFromByteSize(
localIndex const byteSize )
194 return byteSize / byteSizeOfElement< T >();
198 template<
typename T >
199 std::enable_if_t< traits::HasMemberFunction_reserve< T > >
200 reserve( T & value,
localIndex const newCapacity )
201 { value.reserve( newCapacity ); }
203 template<
typename T >
204 std::enable_if_t< !traits::HasMemberFunction_reserve< T > >
209 template<
typename T >
210 std::enable_if_t< traits::HasMemberFunction_capacity< T const >,
localIndex >
211 capacity( T
const & value )
212 {
return value.capacity(); }
214 template<
typename T >
215 std::enable_if_t< !traits::HasMemberFunction_capacity< T const >,
localIndex >
216 capacity( T
const & value )
217 {
return size( value ); }
221 template<
typename T >
222 std::enable_if_t< traits::HasMemberFunction_setName< T > >
224 { value.setName( name ); }
226 template<
typename T >
227 std::enable_if_t< !traits::HasMemberFunction_setName< T > >
231 template<
typename T >
232 std::enable_if_t< traits::HasMemberFunction_move< T > >
234 { value.move( space, touch ); }
236 template<
typename T >
237 std::enable_if_t< !traits::HasMemberFunction_move< T > >
244 template<
typename T >
245 std::enable_if_t< !bufferOps::can_memcpy< typename traits::Pointer< T > > >
246 pushDataToConduitNode( T
const & var, conduit::Node & node )
251 localIndex const byteSize = bufferOps::PackSize( var );
254 conduit::DataType
const dtype( conduitTypeInfo< buffer_unit_type >::id, byteSize );
257 conduit::Node & valuesNode = node[
"__values__" ];
258 valuesNode.set( dtype );
262 bufferOps::Pack< true >( buffer, var );
266 template<
typename T >
267 std::enable_if_t< !bufferOps::can_memcpy< typename traits::Pointer< T > > >
268 pullDataFromConduitNode( T & var, conduit::Node
const & node )
270 conduit::Node
const & valuesNode = node.fetch_child(
"__values__" );
273 localIndex const byteSize = valuesNode.dtype().number_of_elements();
277 localIndex const bytesRead = bufferOps::Unpack( buffer, var );
284 pushDataToConduitNode(
std::string const & var, conduit::Node & node )
288 constexpr
int conduitTypeID = conduitTypeInfo< signed char >::id;
289 conduit::DataType
const dtype( conduitTypeID, var.size() );
291 signed char *
const ptr =
const_cast< signed char *
>(
reinterpret_cast< signed char const *
>( var.data() ) );
292 node[
"__values__" ].set_external( dtype, ptr );
298 pushDataToConduitNode( Path
const & var, conduit::Node & node )
300 pushDataToConduitNode( static_cast< std::string const & >(var), node );
304 template<
typename T >
305 std::enable_if_t< bufferOps::can_memcpy< typename traits::Pointer< T > > >
306 pushDataToConduitNode( T
const & var, conduit::Node & node )
310 constexpr
int conduitTypeID = conduitTypeInfo< typename traits::Pointer< T > >::id;
311 constexpr
int sizeofConduitType = conduitTypeInfo< typename traits::Pointer< T > >::sizeOfConduitType;
313 conduit::DataType
const dtype( conduitTypeID, numBytes / sizeofConduitType );
315 void *
const ptr =
const_cast< void *
>(
static_cast< void const *
>( dataPtr( var ) ) );
316 node[
"__values__" ].set_external( dtype, ptr );
320 template<
typename T >
321 std::enable_if_t< bufferOps::can_memcpy< typename traits::Pointer< T > > >
322 pullDataFromConduitNode( T & var, conduit::Node
const & node )
324 conduit::Node
const & valuesNode = node.fetch_child(
"__values__" );
326 localIndex const byteSize = LvArray::integerConversion< localIndex >( valuesNode.dtype().strided_bytes() );
327 localIndex const numElements = numElementsFromByteSize< T >( byteSize );
329 resize( var, numElements );
331 std::memcpy( dataPtr( var ), valuesNode.data_ptr(), byteSize );
335 template<
typename T >
336 std::enable_if_t< bufferOps::can_memcpy< T > >
337 pullDataFromConduitNode( SortedArray< T > & var, conduit::Node
const & node )
339 conduit::Node
const & valuesNode = node.fetch_child(
"__values__" );
341 localIndex const byteSize = LvArray::integerConversion< localIndex >( valuesNode.dtype().strided_bytes() );
342 localIndex const numElements = numElementsFromByteSize< T >( byteSize );
344 T
const *
const values =
reinterpret_cast< T
const *
>( valuesNode.data_ptr() );
345 var.insert( values, values + numElements );
350 template<
typename T,
int NDIM,
typename PERMUTATION >
351 std::enable_if_t< bufferOps::can_memcpy< T > >
352 pushDataToConduitNode( Array< T, NDIM, PERMUTATION >
const & var,
353 conduit::Node & node )
358 constexpr
int conduitTypeID = conduitTypeInfo< T >::id;
359 constexpr
int sizeofConduitType = conduitTypeInfo< T >::sizeOfConduitType;
360 conduit::DataType
const dtype( conduitTypeID, var.size() *
sizeof( T ) / sizeofConduitType );
361 void *
const ptr =
const_cast< void *
>(
static_cast< void const *
>( var.data() ) );
362 node[
"__values__" ].set_external( dtype, ptr );
366 for(
int i = 0; i < NDIM; ++i )
368 temp[ i ] = var.size( i );
372 constexpr
int const implicitDimensionLength = conduitTypeInfo< T >::numConduitValues;
373 constexpr
bool const hasImplicitDimension = implicitDimensionLength != 1;
374 constexpr
int totalNumDimensions = NDIM + hasImplicitDimension;
375 if( hasImplicitDimension )
377 temp[ NDIM ] = implicitDimensionLength;
381 conduit::DataType
const dimensionType( conduitTypeInfo< localIndex >::id, totalNumDimensions );
382 node[
"__dimensions__" ].set( dimensionType, temp );
385 constexpr std::array< camp::idx_t, NDIM >
const perm = RAJA::as_array< PERMUTATION >::get();
386 for(
int i = 0; i < NDIM; ++i )
388 temp[ i ] = perm[ i ];
391 if( hasImplicitDimension )
396 node[
"__permutation__" ].set( dimensionType, temp );
400 template<
typename T,
int NDIM,
typename PERMUTATION >
401 std::enable_if_t< bufferOps::can_memcpy< T > >
402 pullDataFromConduitNode( Array< T, NDIM, PERMUTATION > & var,
403 conduit::Node
const & node )
406 constexpr
int const implicitDimensionLength = conduitTypeInfo< T >::numConduitValues;
407 constexpr
bool const hasImplicitDimension = implicitDimensionLength != 1;
408 constexpr
int totalNumDimensions = NDIM + hasImplicitDimension;
411 conduit::Node
const & permutationNode = node.fetch_child(
"__permutation__" );
412 GEOSX_ERROR_IF_NE( permutationNode.dtype().number_of_elements(), totalNumDimensions );
414 constexpr std::array< camp::idx_t, NDIM >
const perm = RAJA::as_array< PERMUTATION >::get();
415 camp::idx_t
const *
const permFromConduit = permutationNode.value();
416 for(
int i = 0; i < NDIM; ++i )
419 "The permutation of the data in conduit and the provided Array don't match." );
422 if( hasImplicitDimension )
425 "The permutation of the data in conduit and the provided Array don't match." );
429 conduit::Node
const & dimensionNode = node.fetch_child(
"__dimensions__" );
430 GEOSX_ERROR_IF_NE( dimensionNode.dtype().number_of_elements(), totalNumDimensions );
431 localIndex const *
const dims = dimensionNode.value();
433 if( hasImplicitDimension )
438 var.resize( NDIM, dims );
441 conduit::Node
const & valuesNode = node.fetch_child(
"__values__" );
442 localIndex numBytesFromArray = var.size() *
sizeof( T );
444 std::memcpy( var.data(), valuesNode.data_ptr(), numBytesFromArray );
447 template<
typename T >
448 void pushDataToConduitNode( InterObjectRelation< T >
const & var,
449 conduit::Node & node )
450 {
return pushDataToConduitNode( var.Base(), node ); }
452 template<
typename T >
453 void pullDataFromConduitNode( InterObjectRelation< T > & var,
454 conduit::Node
const & node )
455 {
return pullDataFromConduitNode( var.Base(), node ); }
459 template<
typename T,
int NDIM,
int USD >
460 std::enable_if_t< std::is_arithmetic< T >::value || traits::is_tensorT< T > >
461 addBlueprintField( ArrayView< T const, NDIM, USD >
const & var,
462 conduit::Node & fields,
465 std::vector< std::string >
const & componentNames )
469 using ConduitType =
typename conduitTypeInfo< T >::type;
470 constexpr
int conduitTypeID = conduitTypeInfo< T >::id;
471 constexpr
int numComponentsPerValue = conduitTypeInfo< T >::numConduitValues;
473 localIndex const totalNumberOfComponents = numComponentsPerValue * var.size() / var.size( 0 );
474 if( !componentNames.empty() )
479 var.move( LvArray::MemorySpace::CPU,
false );
481 conduit::DataType dtype( conduitTypeID, var.size( 0 ) );
482 dtype.set_stride(
sizeof( ConduitType ) * numComponentsPerValue * var.strides()[ 0 ] );
486 ( T
const & val,
auto const ... indices )
488 for(
int i = 0; i < numComponentsPerValue; ++i )
491 if( totalNumberOfComponents == 1 )
495 else if( componentNames.empty() )
497 std::string indexString = internal::getIndicesToComponent( val, i, indices ... );
498 indexString.erase( indexString.begin() );
499 indexString.pop_back();
500 indexString.pop_back();
501 name = fieldName + indexString;
505 name = componentNames[ curComponent++ ];
508 conduit::Node & field = fields[ name ];
509 field[
"association" ] =
"element";
510 field[
"volume_dependent" ] =
"false";
511 field[
"topology" ] = topology;
513 void const * pointer = internal::getPointerToComponent( val, i );
514 field[
"values" ].set_external( dtype, const_cast< void * >( pointer ) );
519 template<
typename T >
520 void addBlueprintField( T
const &,
521 conduit::Node & fields,
524 std::vector< std::string >
const & )
526 GEOSX_ERROR(
"Cannot create a mcarray out of " << LvArray::system::demangleType< T >() <<
527 "\nWas trying to write it to " << fields.path() );
530 template<
typename T,
int NDIM,
int USD >
531 std::enable_if_t< std::is_arithmetic< T >::value || traits::is_tensorT< T > >
532 populateMCArray( ArrayView< T const, NDIM, USD >
const & var,
533 conduit::Node & node,
534 std::vector< std::string >
const & componentNames )
538 using ConduitType =
typename conduitTypeInfo< T >::type;
539 constexpr
int conduitTypeID = conduitTypeInfo< T >::id;
540 constexpr
int numComponentsPerValue = conduitTypeInfo< T >::numConduitValues;
542 if( !componentNames.empty() )
547 var.move( LvArray::MemorySpace::CPU,
false );
549 conduit::DataType dtype( conduitTypeID, var.size( 0 ) );
550 dtype.set_stride(
sizeof( ConduitType ) * numComponentsPerValue * var.strides()[ 0 ] );
554 ( T
const & val,
auto const ... indices )
556 for(
int i = 0; i < numComponentsPerValue; ++i )
558 std::string const name = componentNames.empty() ? internal::getIndicesToComponent( val, i, indices ... ) :
559 componentNames[ curComponent++ ];
561 void const * pointer = internal::getPointerToComponent( val, i );
562 node[ name ].set_external( dtype, const_cast< void * >( pointer ) );
567 template<
typename T >
568 void populateMCArray( T
const &,
569 conduit::Node & node,
570 std::vector< std::string >
const & )
572 GEOSX_ERROR(
"Cannot create a mcarray out of " << LvArray::system::demangleType< T >() <<
573 "\nWas trying to write it to " << node.path() );
576 template<
typename T,
int NDIM,
int USD >
577 std::enable_if_t< ( NDIM > 1 ) &&
578 ( std::is_arithmetic< T >::value ),
579 std::unique_ptr<
Array< T, NDIM - 1 > > >
580 averageOverSecondDim( ArrayView< T const, NDIM, USD >
const & var )
582 std::unique_ptr<
Array< T, NDIM - 1 > > ret = std::make_unique<
Array< T, NDIM - 1 > >();
585 newDims[ 0 ] = var.size( 0 );
586 for(
int i = 2; i < NDIM; ++i )
588 newDims[ i - 1 ] = var.size( i );
591 ret->resize( NDIM - 1, newDims );
593 ArrayView< T, NDIM - 1 >
const & output = *ret;
596 forAll< serialPolicy >( var.size( 0 ), [var, numSamples, &output] (
localIndex const i )
609 template<
typename T >
610 std::unique_ptr< int > averageOverSecondDim( T
const & )
612 GEOSX_ERROR(
"Cannot average over the second dimension of " << LvArray::system::demangleType< T >() );
613 return std::unique_ptr< int >( nullptr );
618 template<
bool DO_PACKING,
typename T,
typename IDX >
619 inline std::enable_if_t< bufferOps::is_packable_by_index< T >,
localIndex >
621 {
return bufferOps::PackByIndex< DO_PACKING >( buffer, var, idx ); }
623 template<
bool DO_PACKING,
typename T,
typename IDX >
624 inline std::enable_if_t< !bufferOps::is_packable_by_index< T >,
localIndex >
628 template<
typename T,
typename IDX >
629 inline std::enable_if_t< bufferOps::is_packable_by_index< T >,
localIndex >
631 {
return bufferOps::UnpackByIndex( buffer, var, idx ); }
633 template<
typename T,
typename IDX >
634 inline std::enable_if_t< !bufferOps::is_packable_by_index< T >,
localIndex >
639 template<
bool DO_PACKING,
typename T >
640 inline std::enable_if_t< bufferOps::is_container< T > || bufferOps::can_memcpy< T >,
localIndex >
642 {
return bufferOps::PackDevice< DO_PACKING >( buffer, var ); }
645 template<
bool DO_PACKING,
typename T >
646 inline std::enable_if_t< !bufferOps::is_container< T > && !bufferOps::can_memcpy< T >,
localIndex >
649 GEOSX_ERROR(
"Cannot pack " << LvArray::system::demangleType< T >() <<
" on device." );
653 template<
bool DO_PACKING,
typename T,
typename IDX >
654 inline std::enable_if_t< bufferOps::is_container< T >,
localIndex >
656 {
return bufferOps::PackByIndexDevice< DO_PACKING >( buffer, var, idx ); }
658 template<
bool DO_PACKING,
typename T,
typename IDX >
659 inline std::enable_if_t< !bufferOps::is_container< T >,
localIndex >
662 GEOSX_ERROR(
"Trying to pack data type ("<<
typeid(T).name()<<
") on device but type is not packable by index." );
666 template<
typename T >
667 inline std::enable_if_t< bufferOps::is_container< T >,
localIndex >
669 {
return bufferOps::UnpackDevice( buffer, var ); }
671 template<
typename T >
672 inline std::enable_if_t< !bufferOps::is_container< T >,
localIndex >
676 template<
typename T,
typename IDX >
677 inline std::enable_if_t< bufferOps::is_container< T >,
localIndex >
678 UnpackByIndexDevice(
buffer_unit_type const * & buffer, T
const & var, IDX & idx )
679 {
return bufferOps::UnpackByIndexDevice( buffer, var, idx ); }
681 template<
typename T,
typename IDX >
682 inline std::enable_if_t< !bufferOps::is_container< T >,
localIndex >
687 template<
bool DO_PACKING,
typename T >
690 {
return bufferOps::PackDataDevice< DO_PACKING >( buffer, var ); }
692 template<
bool DO_PACKING,
typename T,
typename IDX >
693 inline std::enable_if_t< bufferOps::is_container< T >,
localIndex >
694 PackDataByIndexDevice(
buffer_unit_type * & buffer, T
const & var, IDX & idx )
695 {
return bufferOps::PackDataByIndexDevice< DO_PACKING >( buffer, var, idx ); }
697 template<
bool DO_PACKING,
typename T,
typename IDX >
698 inline std::enable_if_t< !bufferOps::is_container< T >,
localIndex >
701 GEOSX_ERROR(
"Trying to pack data type ("<<
typeid(T).name()<<
") on device but type is not packable by index." );
705 template<
typename T >
706 inline std::enable_if_t< bufferOps::is_container< T >,
localIndex >
708 {
return bufferOps::UnpackDataDevice( buffer, var ); }
710 template<
typename T >
711 inline std::enable_if_t< !bufferOps::is_container< T >,
localIndex >
715 template<
typename T,
typename IDX >
716 inline std::enable_if_t< bufferOps::is_container< T >,
localIndex >
717 UnpackDataByIndexDevice(
buffer_unit_type const * & buffer, T
const & var, IDX & idx )
718 {
return bufferOps::UnpackDataByIndexDevice( buffer, var, idx ); }
720 template<
typename T,
typename IDX >
721 inline std::enable_if_t< !bufferOps::is_container< T >,
localIndex >
729 #undef RESTART_TYPE_LOGGING 731 #endif // GEOSX_DATAREPOSITORY_WRAPPERHELPERS_HPP_ LvArray::ArrayView< T, NDIM, USD, localIndex, LvArray::ChaiBuffer > ArrayView
Multidimensional array view type. See LvArray:ArrayView for details.
std::string getIndexString()
std::string demangleType()
void forValuesInSlice(T &value, LAMBDA &&f)
Apply the given function to the given value.
Tensor< real64, 3 > R1Tensor
Alias for a local (stack-based) rank-1 tensor type.
double real64
64-bit floating point type.
#define GEOSX_ERROR_IF_GE(lhs, rhs)
Raise a hard error if one value compares greater than or equal to the other.
internal::Helper< T > DefaultValue
A templated alias to hold default values.
#define GEOSX_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
#define GEOSX_ERROR_IF_LE(lhs, rhs)
Raise a hard error if one value compares less than or equal to the other.
signed char buffer_unit_type
Type stored in communication buffers.
#define GEOSX_LOG(...)
Log a message on screen.
MemorySpace
An enum containing the available memory spaces.
#define GEOSX_ERROR(msg)
Raise a hard error and terminate the program.
#define GEOSX_DEBUG_VAR(...)
Mark a debug variable and silence compiler warnings.
LvArray::Array< T, NDIM, PERMUTATION, localIndex, LvArray::ChaiBuffer > Array
Multidimensional array type. See LvArray:Array for details.
std::ptrdiff_t localIndex
Local index type (for indexing objects within an MPI partition).
void forValuesInSliceWithIndices(T &value, LAMBDA &&f, INDICES const ... indices)
Apply the function f to the value value also passing f any indices used to reach value.
void sumOverFirstDimension(ArraySlice< T const, 1, USD_SRC, INDEX_TYPE > const src, T &dst)
Add the values in src to dst.
std::string string
String type.
#define GEOSX_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
#define GEOSX_ERROR_IF_NE_MSG(lhs, rhs, msg)
Raise a hard error if two values are not equal.