20 #ifndef GEOS_DATAREPOSITORY_WRAPPERHELPERS_HPP_ 
   21 #define GEOS_DATAREPOSITORY_WRAPPERHELPERS_HPP_ 
   25 #define RESTART_TYPE_LOGGING 0 
   28 #include "BufferOps.hpp" 
   29 #include "BufferOpsDevice.hpp" 
   35 #include "codingUtilities/traits.hpp" 
   36 #include "LvArray/src/system.hpp" 
   38 #if defined(GEOS_USE_PYGEOSX) 
   39 #include "LvArray/src/python/python.hpp" 
   43 #include <conduit.hpp> 
   48 #if RESTART_TYPE_LOGGING 
   49 #include <unordered_set> 
   54 namespace dataRepository
 
   56 namespace wrapperHelpers
 
   61 inline void logOutputType( 
string const & typeString, 
string const & msg )
 
   63 #if RESTART_TYPE_LOGGING 
   64   static std::unordered_set< string > m_types;
 
   66   if( !m_types.count( typeString ) )
 
   68     m_types.insert( typeString );
 
   77 template< 
typename T, 
typename ... INDICES >
 
   78 string getIndicesToComponent( T 
const &, 
int const component, INDICES 
const ... existingIndices )
 
   81   return LvArray::indexing::getIndexString( existingIndices ... );
 
   84 template< 
typename ... INDICES >
 
   85 string getIndicesToComponent( 
R1Tensor const &, 
int const component, INDICES 
const ... existingIndices )
 
   86 { 
return LvArray::indexing::getIndexString( existingIndices ..., component ); }
 
   88 template< 
typename T >
 
   89 T 
const * getPointerToComponent( T 
const & var, 
int const component )
 
   96 real64 const * getPointerToComponent( 
R1Tensor const & var, 
int const component )
 
   99   return &var[ component ];
 
  104 template< 
typename T >
 
  109   void set( 
integer const, Span< string const > )
 
  111     GEOS_ERROR( 
"Dimension labels are only available in Array wrappers" );
 
  114   Span< string const > get( 
integer const )
 const 
  116     GEOS_ERROR( 
"Dimension labels are only available in Array wrappers" );
 
  121 template< 
typename T, 
int NDIM, 
typename PERM >
 
  122 class ArrayDimLabels< 
Array< T, NDIM, PERM > >
 
  126   void set( 
integer const dim, Span< string const > labels )
 
  130     m_values[dim].resize( labels.size() );
 
  131     std::copy( labels.begin(), labels.end(), m_values[dim].begin() );
 
  134   Span< string const > get( 
integer const dim )
 const 
  138     return { m_values[dim].begin(), m_values[dim].end() };
 
  146 template< 
typename T >
 
  147 inline std::enable_if_t< traits::HasMemberFunction_size< T >, 
size_t >
 
  148 size( T 
const & value )
 
  149 { 
return value.size(); }
 
  151 template< 
typename T >
 
  152 inline std::enable_if_t< !traits::HasMemberFunction_size< T >, 
size_t >
 
  158 dataPtr( 
string & var )
 
  159 { 
return const_cast< char * 
>( var.data() ); }
 
  162 dataPtr( Path & var )
 
  163 { 
return const_cast< char * 
>( var.data() ); }
 
  165 template< 
typename T >
 
  166 inline std::enable_if_t< traits::HasMemberFunction_data< T >, 
typename traits::Pointer< T > >
 
  168 { 
return value.data(); }
 
  170 template< 
typename T >
 
  171 inline std::enable_if_t< !traits::HasMemberFunction_data< T >, 
typename traits::Pointer< T > >
 
  176 inline typename traits::ConstPointer< T >
 
  177 dataPtr( T 
const & value )
 
  178 { 
return dataPtr( 
const_cast< T & 
>( value ) ); }
 
  181 template< 
typename T >
 
  182 inline std::enable_if_t< traits::HasMemberFunction_resize< T > >
 
  184 { value.resize( newSize ); }
 
  186 template< 
typename T >
 
  187 inline std::enable_if_t< !traits::HasMemberFunction_resize< T > >
 
  192 template< 
typename T >
 
  194 resizeDefault( T & value,
 
  196                DefaultValue< T > 
const & defaultValue,
 
  198 { value.resizeDefault( newSize, defaultValue.value ); }
 
  202 template< 
typename T, 
int NDIM, 
typename PERMUTATION >
 
  204 resizeDimensions( Array< T, NDIM, PERMUTATION > & value, 
int num_dims, 
localIndex const * 
const dims )
 
  205 { value.resize( num_dims, dims ); }
 
  207 template< 
typename T >
 
  209 resizeDimensions( T & value, 
int num_dims, 
localIndex const * 
const dims )
 
  216   resize( value, dims[ 0 ] );
 
  220 template< 
typename T >
 
  223 { 
return sizeof( *dataPtr( std::declval< T >() ) ); }
 
  226 template< 
typename T >
 
  228 byteSize( T 
const & value )
 
  229 { 
return wrapperHelpers::size( value ) * byteSizeOfElement< T >(); }
 
  232 template< 
typename T >
 
  234 numElementsFromByteSize( 
localIndex const byteSize )
 
  237   return byteSize / byteSizeOfElement< T >();
 
  241 template< 
typename T >
 
  242 std::enable_if_t< traits::HasMemberFunction_reserve< T > >
 
  243 reserve( T & value, 
localIndex const newCapacity )
 
  244 { value.reserve( newCapacity ); }
 
  246 template< 
typename T >
 
  247 std::enable_if_t< !traits::HasMemberFunction_reserve< T > >
 
  252 template< 
typename T >
 
  253 std::enable_if_t< traits::HasMemberFunction_capacity< T const >, 
localIndex >
 
  254 capacity( T 
const & value )
 
  255 { 
return value.capacity(); }
 
  257 template< 
typename T >
 
  258 std::enable_if_t< !traits::HasMemberFunction_capacity< T const >, 
localIndex >
 
  259 capacity( T 
const & value )
 
  260 { 
return wrapperHelpers::size( value ); }
 
  264 template< 
typename T >
 
  265 std::enable_if_t< traits::HasMemberFunction_setName< T > >
 
  266 setName( T & value, 
string const & name )
 
  267 { value.setName( name ); }
 
  269 template< 
typename T >
 
  270 std::enable_if_t< !traits::HasMemberFunction_setName< T > >
 
  274 template< 
typename T >
 
  275 std::enable_if_t< traits::HasMemberFunction_move< T > >
 
  276 move( T & value, LvArray::MemorySpace 
const space, 
bool const touch )
 
  277 { value.move( space, touch ); }
 
  279 template< 
typename T >
 
  280 std::enable_if_t< !traits::HasMemberFunction_move< T > >
 
  287 template< 
typename T >
 
  288 std::enable_if_t< !bufferOps::can_memcpy< typename traits::Pointer< T > > >
 
  289 pushDataToConduitNode( T 
const & var, conduit::Node & node )
 
  291   internal::logOutputType( LvArray::system::demangleType( var ), 
"Packing for output: " );
 
  294   localIndex const byteSize = bufferOps::PackSize( var );
 
  297   conduit::DataType 
const dtype( conduitTypeInfo< buffer_unit_type >::id, byteSize );
 
  300   conduit::Node & valuesNode = node[ 
"__values__" ];
 
  301   valuesNode.set( dtype );
 
  305   bufferOps::Pack< true >( buffer, var );
 
  309 template< 
typename T >
 
  310 std::enable_if_t< !bufferOps::can_memcpy< typename traits::Pointer< T > > >
 
  311 pullDataFromConduitNode( T & var, conduit::Node 
const & node )
 
  313   conduit::Node 
const & valuesNode = node.fetch_existing( 
"__values__" );
 
  316   localIndex const byteSize = valuesNode.dtype().number_of_elements();
 
  320   localIndex const bytesRead = bufferOps::Unpack( buffer, var );
 
  327 pushDataToConduitNode( 
string const & var, conduit::Node & node )
 
  329   internal::logOutputType( LvArray::system::demangleType( var ), 
"Output via external pointer: " );
 
  331   constexpr 
int conduitTypeID = conduitTypeInfo< signed char >::id;
 
  332   conduit::DataType 
const dtype( conduitTypeID, var.size() );
 
  334   signed char * 
const ptr = 
const_cast< signed char * 
>( 
reinterpret_cast< signed char const * 
>( var.data() ) );
 
  335   node[ 
"__values__" ].set_external( dtype, ptr );
 
  341 pushDataToConduitNode( Path 
const & var, conduit::Node & node )
 
  343   pushDataToConduitNode( 
static_cast< string const & 
>(var), node );
 
  347 template< 
typename T >
 
  348 std::enable_if_t< bufferOps::can_memcpy< typename traits::Pointer< T > > >
 
  349 pushDataToConduitNode( T 
const & var, conduit::Node & node )
 
  351   internal::logOutputType( LvArray::system::demangleType( var ), 
"Output via external pointer: " );
 
  353   constexpr 
int conduitTypeID = conduitTypeInfo< typename traits::Pointer< T > >::id;
 
  354   constexpr 
int sizeofConduitType = conduitTypeInfo< typename traits::Pointer< T > >::sizeOfConduitType;
 
  356   conduit::DataType 
const dtype( conduitTypeID, numBytes / sizeofConduitType );
 
  358   void * 
const ptr = 
const_cast< void * 
>( 
static_cast< void const * 
>( dataPtr( var ) ) );
 
  359   node[ 
"__values__" ].set_external( dtype, ptr );
 
  363 template< 
typename T >
 
  364 std::enable_if_t< bufferOps::can_memcpy< typename traits::Pointer< T > > >
 
  365 pullDataFromConduitNode( T & var, conduit::Node 
const & node )
 
  367   conduit::Node 
const & valuesNode = node.fetch_existing( 
"__values__" );
 
  369   localIndex const byteSize = LvArray::integerConversion< localIndex >( valuesNode.dtype().strided_bytes() );
 
  370   localIndex const numElements = numElementsFromByteSize< T >( byteSize );
 
  372   resize( var, numElements );
 
  374   std::memcpy( dataPtr( var ), valuesNode.data_ptr(), byteSize );
 
  378 template< 
typename T >
 
  379 std::enable_if_t< bufferOps::can_memcpy< T > >
 
  380 pullDataFromConduitNode( SortedArray< T > & var, conduit::Node 
const & node )
 
  382   conduit::Node 
const & valuesNode = node.fetch_existing( 
"__values__" );
 
  384   localIndex const byteSize = LvArray::integerConversion< localIndex >( valuesNode.dtype().strided_bytes() );
 
  385   localIndex const numElements = numElementsFromByteSize< T >( byteSize );
 
  387   T 
const * 
const values = 
reinterpret_cast< T 
const * 
>( valuesNode.data_ptr() );
 
  388   var.insert( values, values + numElements );
 
  393 template< 
typename T, 
int NDIM, 
typename PERMUTATION >
 
  394 std::enable_if_t< bufferOps::can_memcpy< T > >
 
  395 pushDataToConduitNode( Array< T, NDIM, PERMUTATION > 
const & var,
 
  396                        conduit::Node & node )
 
  398   internal::logOutputType( LvArray::system::demangleType( var ), 
"Output array via external pointer: " );
 
  401   constexpr 
int conduitTypeID = conduitTypeInfo< T >::id;
 
  402   constexpr 
int sizeofConduitType = conduitTypeInfo< T >::sizeOfConduitType;
 
  403   conduit::DataType 
const dtype( conduitTypeID, var.size() * 
sizeof( T ) / sizeofConduitType );
 
  404   void * 
const ptr = 
const_cast< void * 
>( 
static_cast< void const * 
>( var.data() ) );
 
  405   node[ 
"__values__" ].set_external( dtype, ptr );
 
  408   camp::idx_t temp[ NDIM + 1 ];
 
  409   for( 
int i = 0; i < NDIM; ++i )
 
  411     temp[ i ] = var.size( i );
 
  415   constexpr 
int const implicitDimensionLength = conduitTypeInfo< T >::numConduitValues;
 
  416   constexpr 
bool const hasImplicitDimension = implicitDimensionLength != 1;
 
  417   constexpr 
int totalNumDimensions = NDIM + hasImplicitDimension;
 
  418   if( hasImplicitDimension )
 
  420     temp[ NDIM ] = implicitDimensionLength;
 
  424   conduit::DataType 
const dimensionType( conduitTypeInfo< camp::idx_t >::id, totalNumDimensions );
 
  425   node[ 
"__dimensions__" ].set( dimensionType, temp );
 
  428   constexpr std::array< camp::idx_t, NDIM > 
const perm = 
to_stdArray( RAJA::as_array< PERMUTATION >::get());
 
  429   for( 
int i = 0; i < NDIM; ++i )
 
  431     temp[ i ] = perm[ i ];
 
  434   if( hasImplicitDimension )
 
  439   node[ 
"__permutation__" ].set( dimensionType, temp );
 
  443 template< 
typename T, 
int NDIM, 
typename PERMUTATION >
 
  444 std::enable_if_t< bufferOps::can_memcpy< T > >
 
  445 pullDataFromConduitNode( Array< T, NDIM, PERMUTATION > & var,
 
  446                          conduit::Node 
const & node )
 
  449   constexpr 
int const implicitDimensionLength = conduitTypeInfo< T >::numConduitValues;
 
  450   constexpr 
bool const hasImplicitDimension = implicitDimensionLength != 1;
 
  451   constexpr 
int totalNumDimensions = NDIM + hasImplicitDimension;
 
  454   conduit::Node 
const & permutationNode = node.fetch_existing( 
"__permutation__" );
 
  455   GEOS_ERROR_IF_NE( permutationNode.dtype().number_of_elements(), totalNumDimensions );
 
  457   constexpr std::array< camp::idx_t, NDIM > 
const perm = 
to_stdArray( RAJA::as_array< PERMUTATION >::get());
 
  458   camp::idx_t 
const * 
const permFromConduit = permutationNode.value();
 
  459   for( 
int i = 0; i < NDIM; ++i )
 
  462                           "The permutation of the data in conduit and the provided Array don't match." );
 
  465   if( hasImplicitDimension )
 
  468                           "The permutation of the data in conduit and the provided Array don't match." );
 
  472   conduit::Node 
const & dimensionNode = node.fetch_existing( 
"__dimensions__" );
 
  473   GEOS_ERROR_IF_NE( dimensionNode.dtype().number_of_elements(), totalNumDimensions );
 
  474   camp::idx_t 
const * 
const dims = dimensionNode.value();
 
  476   if( hasImplicitDimension )
 
  481   var.resize( NDIM, dims );
 
  484   conduit::Node 
const & valuesNode = node.fetch_existing( 
"__values__" );
 
  485   localIndex numBytesFromArray =  var.size() * 
sizeof( T );
 
  487   std::memcpy( var.data(), valuesNode.data_ptr(), numBytesFromArray );
 
  492 template< 
typename T, 
typename INDEX_TYPE >
 
  493 std::enable_if_t< bufferOps::can_memcpy< T > >
 
  494 pushDataToConduitNode( ArrayOfArrays< T, INDEX_TYPE > 
const & var2,
 
  495                        conduit::Node & node )
 
  497   ArrayOfArraysView< T const, INDEX_TYPE > 
const & var = var2.toViewConst();
 
  498   internal::logOutputType( LvArray::system::demangleType( var ), 
"Output array via external pointer: " );
 
  501   INDEX_TYPE 
const numArrays = var.size();
 
  502   conduit::DataType 
const numArraysType( conduitTypeInfo< INDEX_TYPE >::id, 1 );
 
  503   node[ 
"__numberOfArrays__" ].set( numArraysType, 
const_cast< void * 
>( 
static_cast< void const * 
>(&numArrays) ) );
 
  506   INDEX_TYPE 
const * 
const offsets = var.getOffsets();
 
  507   conduit::DataType 
const offsetsType( conduitTypeInfo< INDEX_TYPE >::id, numArrays+1 );
 
  508   node[ 
"__offsets__" ].set_external( offsetsType, 
const_cast< void * 
>( 
static_cast< void const * 
>( offsets ) ) );
 
  511   INDEX_TYPE 
const * 
const sizes = var.getSizes();
 
  512   conduit::DataType 
const sizesType( conduitTypeInfo< INDEX_TYPE >::id, numArrays );
 
  513   node[ 
"__sizes__" ].set_external( sizesType, 
const_cast< void * 
>( 
static_cast< void const * 
>( sizes ) ) );
 
  516   T * 
const values = 
const_cast< T * 
>(var.getValues());
 
  517   for( INDEX_TYPE i = 0; i < numArrays; ++i )
 
  519     INDEX_TYPE 
const curOffset = offsets[ i ];
 
  520     INDEX_TYPE 
const nextOffset = offsets[ i + 1 ];
 
  521     for( INDEX_TYPE j = curOffset + var.sizeOfArray( i ); j < nextOffset; ++j )
 
  523       if constexpr ( std::is_arithmetic< T >::value )
 
  534   constexpr 
int conduitTypeID = conduitTypeInfo< T >::id;
 
  535   constexpr 
int sizeofConduitType = conduitTypeInfo< T >::sizeOfConduitType;
 
  536   conduit::DataType 
const dtype( conduitTypeID, offsets[numArrays] * 
sizeof( T ) / sizeofConduitType );
 
  539   node[ 
"__values__" ].set_external( dtype, values );
 
  542 template< 
typename T, 
typename INDEX_TYPE >
 
  543 std::enable_if_t< bufferOps::can_memcpy< T > >
 
  544 pullDataFromConduitNode( ArrayOfArrays< T, INDEX_TYPE > & var,
 
  545                          conduit::Node 
const & node )
 
  549   conduit::Node 
const & numArraysNode = node.fetch_existing( 
"__numberOfArrays__" );
 
  550   INDEX_TYPE 
const * 
const numArrays = numArraysNode.value();
 
  553   conduit::Node 
const & offsetsNode = node.fetch_existing( 
"__offsets__" );
 
  554   conduit::DataType 
const & offsetsDataType = offsetsNode.dtype();
 
  555   INDEX_TYPE 
const * 
const offsets = offsetsNode.value();
 
  556   INDEX_TYPE 
const sizeOffsets = offsetsDataType.number_of_elements();
 
  559   conduit::Node 
const & sizesNode = node.fetch_existing( 
"__sizes__" );
 
  560   conduit::DataType 
const & sizesDataType = sizesNode.dtype();
 
  561   INDEX_TYPE 
const * 
const sizes = sizesNode.value();
 
  562   INDEX_TYPE 
const sizeSizes = sizesDataType.number_of_elements();
 
  569   conduit::Node 
const & valuesNode = node.fetch_existing( 
"__values__" );
 
  570   conduit::DataType 
const & valuesDataType = valuesNode.dtype();
 
  571   const INDEX_TYPE valuesSize = valuesDataType.number_of_elements();
 
  574   INDEX_TYPE 
const arraySizeEstimate = (*numArrays)==0 ? 0 : valuesSize / (*numArrays);
 
  575   var.resize( *numArrays, arraySizeEstimate );
 
  576   var.reserveValues( valuesSize );
 
  580   for( INDEX_TYPE i = 0; i < *numArrays; ++i )
 
  582     INDEX_TYPE 
const arrayAllocation = offsets[i+1] - offsets[i];
 
  583     var.setCapacityOfArray( i, arrayAllocation );
 
  584     var.resizeArray( i, sizes[ i ] );
 
  585     allocatedSize += arrayAllocation;
 
  595   ArrayOfArraysView< T const, INDEX_TYPE > 
const & varView = var.toViewConst();
 
  596   INDEX_TYPE 
const * 
const varOffsets = varView.getOffsets();
 
  597   INDEX_TYPE 
const * 
const varSizes = varView.getSizes();
 
  603   for( INDEX_TYPE i = 0; i<*numArrays; ++i )
 
  610   localIndex numBytesFromArray =  allocatedSize * 
sizeof( T );
 
  612   std::memcpy( 
const_cast< T * 
>(varView.getValues()), valuesNode.data_ptr(), numBytesFromArray );
 
  617 template< 
typename T >
 
  618 void pushDataToConduitNode( InterObjectRelation< T > 
const & var,
 
  619                             conduit::Node & node )
 
  620 {
return pushDataToConduitNode( var.base(), node ); }
 
  622 template< 
typename T >
 
  623 void pullDataFromConduitNode( InterObjectRelation< T > & var,
 
  624                               conduit::Node 
const & node )
 
  625 { 
return pullDataFromConduitNode( var.base(), node ); }
 
  629 template< 
typename T, 
int NDIM, 
int USD >
 
  630 std::enable_if_t< std::is_arithmetic< T >::value || traits::is_tensorT< T > >
 
  631 addBlueprintField( ArrayView< T const, NDIM, USD > 
const & var,
 
  632                    conduit::Node & fields,
 
  633                    string const & fieldName,
 
  634                    string const & topology,
 
  635                    stdVector< string > 
const & componentNames )
 
  639   using ConduitType = 
typename conduitTypeInfo< T >::type;
 
  640   constexpr 
int conduitTypeID = conduitTypeInfo< T >::id;
 
  641   constexpr 
int numComponentsPerValue = conduitTypeInfo< T >::numConduitValues;
 
  643   localIndex const totalNumberOfComponents = numComponentsPerValue * var.size() / var.size( 0 );
 
  644   if( !componentNames.empty() )
 
  649   var.move( hostMemorySpace, 
false );
 
  651   conduit::DataType dtype( conduitTypeID, var.size( 0 ) );
 
  652   dtype.set_stride( 
sizeof( ConduitType ) * numComponentsPerValue * var.strides()[ 0 ] );
 
  655   LvArray::forValuesInSliceWithIndices( var[ 0 ], [&fields, &fieldName, &topology, &componentNames, totalNumberOfComponents, &dtype, &curComponent]
 
  656                                           ( T 
const & val, 
auto const ... indices )
 
  658     for( 
int i = 0; i < numComponentsPerValue; ++i )
 
  661       if( totalNumberOfComponents == 1 )
 
  665       else if( componentNames.empty() )
 
  667         string indexString = internal::getIndicesToComponent( val, i, indices ... );
 
  668         indexString.erase( indexString.begin() );
 
  669         indexString.pop_back();
 
  670         indexString.pop_back();
 
  671         name = fieldName + indexString;
 
  675         name = componentNames[ curComponent++ ];
 
  678       conduit::Node & field = fields[ name ];
 
  679       field[ 
"association" ] = 
"element";
 
  680       field[ 
"volume_dependent" ] = 
"false";
 
  681       field[ 
"topology" ] = topology;
 
  683       void const * pointer = internal::getPointerToComponent( val, i );
 
  684       field[ 
"values" ].set_external( dtype, 
const_cast< void * 
>( pointer ) );
 
  689 template< 
typename T >
 
  690 void addBlueprintField( T 
const &,
 
  691                         conduit::Node & fields,
 
  694                         stdVector< string > 
const & )
 
  696   GEOS_ERROR( 
"Cannot create a mcarray out of " << LvArray::system::demangleType< T >() <<
 
  697               "\nWas trying to write it to " << fields.path() );
 
  701 template< 
typename T, 
int NDIM, 
int USD >
 
  702 std::enable_if_t< std::is_arithmetic< T >::value || traits::is_tensorT< T > >
 
  703 populateMCArray( ArrayView< T const, NDIM, USD > 
const & var,
 
  704                  conduit::Node & node,
 
  705                  stdVector< string > 
const & componentNames )
 
  709   using ConduitType = 
typename conduitTypeInfo< T >::type;
 
  710   constexpr 
int conduitTypeID = conduitTypeInfo< T >::id;
 
  711   constexpr 
int numComponentsPerValue = conduitTypeInfo< T >::numConduitValues;
 
  713   if( !componentNames.empty() )
 
  718   var.move( hostMemorySpace, 
false );
 
  720   conduit::DataType dtype( conduitTypeID, var.size( 0 ) );
 
  721   dtype.set_stride( 
sizeof( ConduitType ) * numComponentsPerValue * var.strides()[ 0 ] );
 
  724   LvArray::forValuesInSliceWithIndices( var[ 0 ], [&componentNames, &node, &dtype, &curComponent]
 
  725                                           ( T 
const & val, 
auto const ... indices )
 
  727     for( 
int i = 0; i < numComponentsPerValue; ++i )
 
  729       string const name = componentNames.empty() ? internal::getIndicesToComponent( val, i, indices ... ) :
 
  730                           componentNames[ curComponent++ ];
 
  732       void const * pointer = internal::getPointerToComponent( val, i );
 
  733       node[ name ].set_external( dtype, 
const_cast< void * 
>( pointer ) );
 
  738 template< 
typename T >
 
  739 void populateMCArray( T 
const &,
 
  740                       conduit::Node & node,
 
  741                       stdVector< string > 
const & )
 
  743   GEOS_ERROR( 
"Cannot create a mcarray out of " << LvArray::system::demangleType< T >() <<
 
  744               "\nWas trying to write it to " << node.path() );
 
  748 template< 
typename T >
 
  749 std::enable_if_t< std::is_arithmetic< T >::value, std::unique_ptr< Array< T, 1 > > >
 
  750 averageOverSecondDim( ArrayView< T const, 1, 0 > 
const & var )
 
  752   std::unique_ptr< Array< T, 1 > > ret = std::make_unique< Array< T, 1 > >();
 
  754   ret->resize( var.size() );
 
  755   ret->template setValues< serialPolicy >( var );
 
  760 template< 
typename T, 
int NDIM, 
int USD >
 
  761 std::enable_if_t< std::is_arithmetic< T >::value, std::unique_ptr< 
Array< T, NDIM - 1 > > >
 
  762 averageOverSecondDim( ArrayView< T const, NDIM, USD > 
const & var )
 
  764   std::unique_ptr< 
Array< T, NDIM - 1 > > ret = std::make_unique< 
Array< T, NDIM - 1 > >();
 
  767   newDims[ 0 ] = var.size( 0 );
 
  768   for( 
int i = 2; i < NDIM; ++i )
 
  770     newDims[ i - 1 ] = var.size( i );
 
  773   ret->resize( NDIM - 1, newDims );
 
  775   ArrayView< T, NDIM - 1 > 
const & output = *ret;
 
  778   forAll< serialPolicy >( var.size( 0 ), [var, numSamples, &output] ( 
localIndex const i )
 
  780     LvArray::sumOverFirstDimension( var[ i ], output[ i ] );
 
  782     LvArray::forValuesInSlice( output[ i ], [numSamples] ( T & val )
 
  791 template< 
typename T >
 
  792 std::unique_ptr< int > averageOverSecondDim( T 
const & )
 
  794   GEOS_ERROR( 
"Cannot average over the second dimension of " << LvArray::system::demangleType< T >() );
 
  795   return std::unique_ptr< int >( 
nullptr );
 
  798 template< 
typename T, 
int NDIM, 
int USD >
 
  799 int numArrayDims( ArrayView< T const, NDIM, USD > 
const & 
GEOS_UNUSED_PARAM( var ) )
 
  804 template< 
typename T >
 
  810 template< 
typename T >
 
  816 template< 
typename T, 
int NDIM, 
int USD >
 
  817 localIndex numArrayComp( ArrayView< T const, NDIM, USD > 
const & var )
 
  819   return LvArray::indexing::multiplyAll< NDIM - 1 >( var.dims() + 1 );
 
  822 template< 
typename T >
 
  828 template< 
typename T >
 
  834 template< 
bool DO_PACKING, 
typename T, 
typename IDX >
 
  835 inline std::enable_if_t< bufferOps::is_packable_by_index< T >, 
localIndex >
 
  837 { 
return bufferOps::PackByIndex< DO_PACKING >( buffer, var, idx ); }
 
  839 template< 
bool DO_PACKING, 
typename T, 
typename IDX >
 
  840 inline std::enable_if_t< !bufferOps::is_packable_by_index< T >, 
localIndex >
 
  843   GEOS_ERROR( 
"Trying to pack data type (" << LvArray::system::demangleType< T >() << 
") by index. Operation not supported." );
 
  847 template< 
typename T, 
typename IDX >
 
  848 inline std::enable_if_t< bufferOps::is_packable_by_index< T >, 
localIndex >
 
  850 { 
return bufferOps::UnpackByIndex( buffer, var, idx ); }
 
  852 template< 
typename T, 
typename IDX >
 
  853 inline std::enable_if_t< !bufferOps::is_packable_by_index< T >, 
localIndex >
 
  856   GEOS_ERROR( 
"Trying to unpack data type (" << LvArray::system::demangleType< T >() << 
") by index. Operation not supported." );
 
  861 template< 
bool DO_PACKING, 
typename T >
 
  862 inline std::enable_if_t< bufferOps::is_container< T > || bufferOps::can_memcpy< T >, 
localIndex >
 
  863 PackDevice( 
buffer_unit_type * & buffer, T 
const & var, parallelDeviceEvents & events )
 
  864 { 
return bufferOps::PackDevice< DO_PACKING >( buffer, var, events ); }
 
  867 template< 
bool DO_PACKING, 
typename T >
 
  868 inline std::enable_if_t< !bufferOps::is_container< T > && !bufferOps::can_memcpy< T >, 
localIndex >
 
  871   GEOS_ERROR( 
"Trying to pack data type (" << LvArray::system::demangleType< T >() << 
") on device. Operation not supported." );
 
  875 template< 
bool DO_PACKING, 
typename T, 
typename IDX >
 
  876 inline std::enable_if_t< bufferOps::is_container< T >, 
localIndex >
 
  877 PackByIndexDevice( 
buffer_unit_type * & buffer, T 
const & var, IDX & idx, parallelDeviceEvents & events )
 
  878 { 
return bufferOps::PackByIndexDevice< DO_PACKING >( buffer, var, idx, events ); }
 
  880 template< 
bool DO_PACKING, 
typename T, 
typename IDX >
 
  881 inline std::enable_if_t< !bufferOps::is_container< T >, 
localIndex >
 
  882 PackByIndexDevice( 
buffer_unit_type * &, T 
const &, IDX &, parallelDeviceEvents & )
 
  884   GEOS_ERROR( 
"Trying to pack data type (" << LvArray::system::demangleType< T >() << 
") by index on device. Operation not supported." );
 
  888 template< 
typename T >
 
  889 inline std::enable_if_t< bufferOps::is_container< T >, 
localIndex >
 
  890 UnpackDevice( 
buffer_unit_type const * & buffer, T 
const & var, parallelDeviceEvents & events )
 
  891 { 
return bufferOps::UnpackDevice( buffer, var, events ); }
 
  893 template< 
typename T >
 
  894 inline std::enable_if_t< !bufferOps::is_container< T >, 
localIndex >
 
  895 UnpackDevice( 
buffer_unit_type const * &, T 
const &, parallelDeviceEvents & )
 
  897   GEOS_ERROR( 
"Trying to unpack data type (" << LvArray::system::demangleType< T >() << 
") on device. Operation not supported." );
 
  901 template< 
typename T, 
typename IDX >
 
  902 inline std::enable_if_t< bufferOps::is_container< T >, 
localIndex >
 
  903 UnpackByIndexDevice( 
buffer_unit_type const * & buffer, T 
const & var, IDX & idx, parallelDeviceEvents & events, MPI_Op op=MPI_REPLACE )
 
  904 { 
return bufferOps::UnpackByIndexDevice( buffer, var, idx, events, op ); }
 
  906 template< 
typename T, 
typename IDX >
 
  907 inline std::enable_if_t< !bufferOps::is_container< T >, 
localIndex >
 
  908 UnpackByIndexDevice( 
buffer_unit_type const * &, T &, IDX &, parallelDeviceEvents &, MPI_Op )
 
  910   GEOS_ERROR( 
"Trying to unpack data type (" << LvArray::system::demangleType< T >() << 
") by index on device. Operation not supported." );
 
  915 template< 
bool DO_PACKING, 
typename T >
 
  917 PackDataDevice( 
buffer_unit_type * & buffer, T 
const & var, parallelDeviceEvents & events )
 
  918 { 
return bufferOps::PackDataDevice< DO_PACKING >( buffer, var, events ); }
 
  920 template< 
bool DO_PACKING, 
typename T, 
typename IDX >
 
  921 inline std::enable_if_t< bufferOps::is_container< T >, 
localIndex >
 
  922 PackDataByIndexDevice( 
buffer_unit_type * & buffer, T 
const & var, IDX & idx, parallelDeviceEvents & events )
 
  923 { 
return bufferOps::PackDataByIndexDevice< DO_PACKING >( buffer, var, idx, events ); }
 
  925 template< 
bool DO_PACKING, 
typename T, 
typename IDX >
 
  926 inline std::enable_if_t< !bufferOps::is_container< T >, 
localIndex >
 
  927 PackDataByIndexDevice( 
buffer_unit_type * &, T 
const &, IDX &, parallelDeviceEvents & )
 
  929   GEOS_ERROR( 
"Trying to pack data type (" << LvArray::system::demangleType< T >() << 
") by index on device. Operation not supported." );
 
  933 template< 
typename T >
 
  934 inline std::enable_if_t< bufferOps::is_container< T >, 
localIndex >
 
  935 UnpackDataDevice( 
buffer_unit_type const * & buffer, T 
const & var, parallelDeviceEvents & events )
 
  936 { 
return bufferOps::UnpackDataDevice( buffer, var, events ); }
 
  938 template< 
typename T >
 
  939 inline std::enable_if_t< !bufferOps::is_container< T >, 
localIndex >
 
  940 UnpackDataDevice( 
buffer_unit_type const * &, T 
const &, parallelDeviceEvents & )
 
  942   GEOS_ERROR( 
"Trying to unpack data type (" << LvArray::system::demangleType< T >() << 
") on device. Operation not supported." );
 
  946 template< 
typename T, 
typename IDX >
 
  947 inline std::enable_if_t< bufferOps::is_container< T >, 
localIndex >
 
  948 UnpackDataByIndexDevice( 
buffer_unit_type const * & buffer, T 
const & var, IDX & idx, parallelDeviceEvents & events, MPI_Op op )
 
  949 { 
return bufferOps::UnpackDataByIndexDevice( buffer, var, idx, events, op ); }
 
  951 template< 
typename T, 
typename IDX >
 
  952 inline std::enable_if_t< !bufferOps::is_container< T >, 
localIndex >
 
  953 UnpackDataByIndexDevice( 
buffer_unit_type const * &, T 
const &, IDX &, parallelDeviceEvents &, MPI_Op )
 
  955   GEOS_ERROR( 
"Trying to unpack data type (" << LvArray::system::demangleType< T >() << 
") by index on device. Operation not supported." );
 
  959 #if defined(GEOS_USE_PYGEOSX) 
  961 template< 
typename T >
 
  962 inline std::enable_if_t< LvArray::python::CanCreate< T >, PyObject * >
 
  963 createPythonObject( T & 
object )
 
  964 { 
return LvArray::python::create( 
object ); }
 
  966 template< 
typename T >
 
  967 inline std::enable_if_t< !LvArray::python::CanCreate< T >, PyObject * >
 
  968 createPythonObject( T & )
 
  977 #undef RESTART_TYPE_LOGGING 
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
#define GEOS_DEBUG_VAR(...)
Mark a debug variable and silence compiler warnings.
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
#define GEOS_ERROR_IF_LE(lhs, rhs)
Raise a hard error if one value compares less than or equal to the other.
#define GEOS_ERROR_IF_LT(lhs, rhs)
Raise a hard error if one value compares less than the other.
#define GEOS_ERROR_IF_GE(lhs, rhs)
Raise a hard error if one value compares greater than or equal to the other.
#define GEOS_LOG(...)
Log a message on screen.
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
#define GEOS_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
#define GEOS_ERROR_IF_NE_MSG(lhs, rhs, msg)
Raise a hard error if two values are not equal.
stdVector< string > string_array
A 1-dimensional array of geos::string types.
LvArray::Array< T, NDIM, PERMUTATION, localIndex, LvArray::ChaiBuffer > Array
Multidimensional array type. See LvArray:Array for details.
std::set< T > set
A set of local indices.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
constexpr stdArray< T, N > to_stdArray(std::array< T, N > const &arr)
Convert an std::array to an stdArray.
Tensor< real64, 3 > R1Tensor
Alias for a local (stack-based) rank-1 tensor type.
signed char buffer_unit_type
Type stored in communication buffers.
int integer
Signed integer type.
LvArray::ArrayView< T, NDIM, USD, localIndex, LvArray::ChaiBuffer > ArrayView
Multidimensional array view type. See LvArray:ArrayView for details.