GEOSX
wrapperHelpers.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 Total, S.A
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
19 #ifndef GEOSX_DATAREPOSITORY_WRAPPERHELPERS_HPP_
20 #define GEOSX_DATAREPOSITORY_WRAPPERHELPERS_HPP_
21 
22 
24 #define RESTART_TYPE_LOGGING 0
25 
26 // Source includes
27 #include "BufferOps.hpp"
28 #include "BufferOpsDevice.hpp"
29 #include "DefaultValue.hpp"
30 #include "ConduitRestart.hpp"
31 #include "common/DataTypes.hpp"
32 #include "common/GeosxMacros.hpp"
33 #include "codingUtilities/traits.hpp"
34 
35 // TPL includes
36 #include <conduit.hpp>
37 
38 // System includes
39 #include <cstring>
40 
41 #if RESTART_TYPE_LOGGING
42 #include <unordered_set>
43 #endif
44 
45 namespace geosx
46 {
47 namespace dataRepository
48 {
49 namespace wrapperHelpers
50 {
51 namespace internal
52 {
53 
54 inline void logOutputType( std::string const & typeString, std::string const & msg )
55 {
56 #if RESTART_TYPE_LOGGING
57  static std::unordered_set< std::string > m_types;
58 
59  if( !m_types.count( typeString ) )
60  {
61  m_types.insert( typeString );
62  GEOSX_LOG( msg << typeString );
63  }
64 #else
65  GEOSX_DEBUG_VAR( typeString );
66  GEOSX_DEBUG_VAR( msg );
67 #endif
68 }
69 
70 template< typename T, typename ... INDICES >
71 std::string getIndicesToComponent( T const &, int const component, INDICES const ... existingIndices )
72 {
73  GEOSX_ERROR_IF_NE( component, 0 );
74  return LvArray::indexing::getIndexString( existingIndices ... );
75 }
76 
77 template< typename ... INDICES >
78 std::string getIndicesToComponent( R1Tensor const &, int const component, INDICES const ... existingIndices )
79 { return LvArray::indexing::getIndexString( existingIndices ..., component ); }
80 
81 template< typename T >
82 T const * getPointerToComponent( T const & var, int const component )
83 {
84  GEOSX_ERROR_IF_NE( component, 0 );
85  return &var;
86 }
87 
88 inline
89 real64 const * getPointerToComponent( R1Tensor const & var, int const component )
90 {
91  GEOSX_ERROR_IF_GE( component, 3 );
92  return &var[ component ];
93 }
94 
95 } // namespace internal
96 
97 
98 
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() ); }
103 
104 template< typename T >
105 inline std::enable_if_t< !traits::HasMemberFunction_size< T >, localIndex >
106 size( T const & GEOSX_UNUSED_PARAM( value ) )
107 { return 1; }
108 
109 
110 inline char *
111 dataPtr( std::string & var )
112 { return const_cast< char * >( var.data() ); }
113 
114 inline char *
115 dataPtr( Path & var )
116 { return const_cast< char * >( var.data() ); }
117 
118 template< typename T >
119 inline std::enable_if_t< traits::HasMemberFunction_data< T >, typename traits::Pointer< T > >
120 dataPtr( T & value )
121 { return value.data(); }
122 
123 template< typename T >
124 inline std::enable_if_t< !traits::HasMemberFunction_data< T >, typename traits::Pointer< T > >
125 dataPtr( T & value )
126 { return &value; }
127 
128 template< class T >
129 inline typename traits::ConstPointer< T >
130 dataPtr( T const & value )
131 { return dataPtr( const_cast< T & >( value ) ); }
132 
133 
134 template< typename T >
135 inline std::enable_if_t< traits::HasMemberFunction_resize< T > >
136 resize( T & value, localIndex const newSize )
137 { value.resize( newSize ); }
138 
139 template< typename T >
140 inline std::enable_if_t< !traits::HasMemberFunction_resize< T > >
141 resize( T & GEOSX_UNUSED_PARAM( value ),
142  localIndex const GEOSX_UNUSED_PARAM( newSize ) )
143 {}
144 
145 
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,
149  localIndex const newSize,
150  DefaultValue< Array< T, NDIM, PERMUTATION > > const & defaultValue )
151 { value.resizeDefault( newSize, defaultValue.value ); }
152 
153 template< typename T >
154 inline void
155 resizeDefault( T & value, localIndex const newSize, DefaultValue< T > const & GEOSX_UNUSED_PARAM( defaultValue ) )
156 { resize( value, newSize ); }
157 
158 
159 template< typename T, int NDIM, typename PERMUTATION >
160 inline void
161 resizeDimensions( Array< T, NDIM, PERMUTATION > & value, int num_dims, localIndex const * const dims )
162 { value.resize( num_dims, dims ); }
163 
164 template< typename T >
165 inline void
166 resizeDimensions( T & value, int num_dims, localIndex const * const dims )
167 {
168  if( num_dims != 1 )
169  {
170  GEOSX_ERROR( "Data is not multidimensional" );
171  return;
172  }
173  resize( value, dims[ 0 ] );
174 }
175 
176 
177 template< typename T >
178 inline localIndex
179 byteSizeOfElement()
180 { return sizeof( *dataPtr( std::declval< T >() ) ); }
181 
182 
183 template< typename T >
184 inline localIndex
185 byteSize( T const & value )
186 { return size( value ) * byteSizeOfElement< T >(); }
187 
188 
189 template< typename T >
190 inline localIndex
191 numElementsFromByteSize( localIndex const byteSize )
192 {
193  GEOSX_ERROR_IF_NE( byteSize % byteSizeOfElement< T >(), 0 );
194  return byteSize / byteSizeOfElement< T >();
195 }
196 
197 
198 template< typename T >
199 std::enable_if_t< traits::HasMemberFunction_reserve< T > >
200 reserve( T & value, localIndex const newCapacity )
201 { value.reserve( newCapacity ); }
202 
203 template< typename T >
204 std::enable_if_t< !traits::HasMemberFunction_reserve< T > >
205 reserve( T & GEOSX_UNUSED_PARAM( value ), localIndex const GEOSX_UNUSED_PARAM( newCapacity ) )
206 {}
207 
208 
209 template< typename T >
210 std::enable_if_t< traits::HasMemberFunction_capacity< T const >, localIndex >
211 capacity( T const & value )
212 { return value.capacity(); }
213 
214 template< typename T >
215 std::enable_if_t< !traits::HasMemberFunction_capacity< T const >, localIndex >
216 capacity( T const & value )
217 { return size( value ); }
218 
219 
220 
221 template< typename T >
222 std::enable_if_t< traits::HasMemberFunction_setName< T > >
223 setName( T & value, std::string const & name )
224 { value.setName( name ); }
225 
226 template< typename T >
227 std::enable_if_t< !traits::HasMemberFunction_setName< T > >
228 setName( T & GEOSX_UNUSED_PARAM( value ), std::string const & GEOSX_UNUSED_PARAM( name ) )
229 {}
230 
231 template< typename T >
232 std::enable_if_t< traits::HasMemberFunction_move< T > >
233 move( T & value, LvArray::MemorySpace const space, bool const touch )
234 { value.move( space, touch ); }
235 
236 template< typename T >
237 std::enable_if_t< !traits::HasMemberFunction_move< T > >
238 move( T & GEOSX_UNUSED_PARAM( value ),
240  bool const GEOSX_UNUSED_PARAM( touch ) )
241 {}
242 
243 // This is for an object that needs to be packed.
244 template< typename T >
245 std::enable_if_t< !bufferOps::can_memcpy< typename traits::Pointer< T > > >
246 pushDataToConduitNode( T const & var, conduit::Node & node )
247 {
248  internal::logOutputType( LvArray::system::demangleType( var ), "Packing for output: " );
249 
250  // Get the number of bytes in the packed object.
251  localIndex const byteSize = bufferOps::PackSize( var );
252 
253  // Create a conduit data type that describes the array.
254  conduit::DataType const dtype( conduitTypeInfo< buffer_unit_type >::id, byteSize );
255 
256  // Allocate the array in the "__values__" child.
257  conduit::Node & valuesNode = node[ "__values__" ];
258  valuesNode.set( dtype );
259 
260  // Get the pointer to the array and pack the object into it.
261  buffer_unit_type * buffer = valuesNode.value();
262  bufferOps::Pack< true >( buffer, var );
263 }
264 
265 // This is for an object that needs to be packed.
266 template< typename T >
267 std::enable_if_t< !bufferOps::can_memcpy< typename traits::Pointer< T > > >
268 pullDataFromConduitNode( T & var, conduit::Node const & node )
269 {
270  conduit::Node const & valuesNode = node.fetch_child( "__values__" );
271 
272  // Get the number of bytes in the array and a pointer to the array.
273  localIndex const byteSize = valuesNode.dtype().number_of_elements();
274  buffer_unit_type const * buffer = valuesNode.value();
275 
276  // Unpack the object from the array.
277  localIndex const bytesRead = bufferOps::Unpack( buffer, var );
278  GEOSX_ERROR_IF_NE( bytesRead, byteSize );
279 }
280 
281 // This is for an std::string since the type of char is different on different platforms :(.
282 inline
283 void
284 pushDataToConduitNode( std::string const & var, conduit::Node & node )
285 {
286  internal::logOutputType( LvArray::system::demangleType( var ), "Output via external pointer: " );
287 
288  constexpr int conduitTypeID = conduitTypeInfo< signed char >::id;
289  conduit::DataType const dtype( conduitTypeID, var.size() );
290 
291  signed char * const ptr = const_cast< signed char * >( reinterpret_cast< signed char const * >( var.data() ) );
292  node[ "__values__" ].set_external( dtype, ptr );
293 }
294 
295 // This is for Path since it derives from std::string. See overload for std::string.
296 inline
297 void
298 pushDataToConduitNode( Path const & var, conduit::Node & node )
299 {
300  pushDataToConduitNode( static_cast< std::string const & >(var), node );
301 }
302 
303 // This is for an object that doesn't need to be packed but isn't an LvArray.
304 template< typename T >
305 std::enable_if_t< bufferOps::can_memcpy< typename traits::Pointer< T > > >
306 pushDataToConduitNode( T const & var, conduit::Node & node )
307 {
308  internal::logOutputType( LvArray::system::demangleType( var ), "Output via external pointer: " );
309 
310  constexpr int conduitTypeID = conduitTypeInfo< typename traits::Pointer< T > >::id;
311  constexpr int sizeofConduitType = conduitTypeInfo< typename traits::Pointer< T > >::sizeOfConduitType;
312  localIndex const numBytes = byteSize( var );
313  conduit::DataType const dtype( conduitTypeID, numBytes / sizeofConduitType );
314 
315  void * const ptr = const_cast< void * >( static_cast< void const * >( dataPtr( var ) ) );
316  node[ "__values__" ].set_external( dtype, ptr );
317 }
318 
319 // This is for an object that doesn't need to be packed but isn't an LvArray or a SortedArray.
320 template< typename T >
321 std::enable_if_t< bufferOps::can_memcpy< typename traits::Pointer< T > > >
322 pullDataFromConduitNode( T & var, conduit::Node const & node )
323 {
324  conduit::Node const & valuesNode = node.fetch_child( "__values__" );
325 
326  localIndex const byteSize = LvArray::integerConversion< localIndex >( valuesNode.dtype().strided_bytes() );
327  localIndex const numElements = numElementsFromByteSize< T >( byteSize );
328 
329  resize( var, numElements );
330 
331  std::memcpy( dataPtr( var ), valuesNode.data_ptr(), byteSize );
332 }
333 
334 // This is for a SortedArray that doesn't need to be packed.
335 template< typename T >
336 std::enable_if_t< bufferOps::can_memcpy< T > >
337 pullDataFromConduitNode( SortedArray< T > & var, conduit::Node const & node )
338 {
339  conduit::Node const & valuesNode = node.fetch_child( "__values__" );
340 
341  localIndex const byteSize = LvArray::integerConversion< localIndex >( valuesNode.dtype().strided_bytes() );
342  localIndex const numElements = numElementsFromByteSize< T >( byteSize );
343 
344  T const * const values = reinterpret_cast< T const * >( valuesNode.data_ptr() );
345  var.insert( values, values + numElements );
346 }
347 
348 
349 // This is an LvArray that doesn't need to be packed.
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 )
354 {
355  internal::logOutputType( LvArray::system::demangleType( var ), "Output array via external pointer: " );
356 
357  // Push the data into conduit
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 );
363 
364  // Create a copy of the dimensions
365  localIndex temp[ NDIM + 1 ];
366  for( int i = 0; i < NDIM; ++i )
367  {
368  temp[ i ] = var.size( i );
369  }
370 
371  // If T is something like a Tensor than there is an extra implicit dimension.
372  constexpr int const implicitDimensionLength = conduitTypeInfo< T >::numConduitValues;
373  constexpr bool const hasImplicitDimension = implicitDimensionLength != 1;
374  constexpr int totalNumDimensions = NDIM + hasImplicitDimension;
375  if( hasImplicitDimension )
376  {
377  temp[ NDIM ] = implicitDimensionLength;
378  }
379 
380  // push the dimensions into the node
381  conduit::DataType const dimensionType( conduitTypeInfo< localIndex >::id, totalNumDimensions );
382  node[ "__dimensions__" ].set( dimensionType, temp );
383 
384  // Create a copy of the permutation
385  constexpr std::array< camp::idx_t, NDIM > const perm = RAJA::as_array< PERMUTATION >::get();
386  for( int i = 0; i < NDIM; ++i )
387  {
388  temp[ i ] = perm[ i ];
389  }
390 
391  if( hasImplicitDimension )
392  {
393  temp[ NDIM ] = NDIM;
394  }
395 
396  node[ "__permutation__" ].set( dimensionType, temp );
397 }
398 
399 // This is an LvArray that doesn't need to be packed.
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 )
404 {
405  // Get the number of dimensions written out, accounting for an implicit dimension and the permutation.
406  constexpr int const implicitDimensionLength = conduitTypeInfo< T >::numConduitValues;
407  constexpr bool const hasImplicitDimension = implicitDimensionLength != 1;
408  constexpr int totalNumDimensions = NDIM + hasImplicitDimension;
409 
410  // Check that the permutations match.
411  conduit::Node const & permutationNode = node.fetch_child( "__permutation__" );
412  GEOSX_ERROR_IF_NE( permutationNode.dtype().number_of_elements(), totalNumDimensions );
413 
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 )
417  {
418  GEOSX_ERROR_IF_NE_MSG( permFromConduit[ i ], perm[ i ],
419  "The permutation of the data in conduit and the provided Array don't match." );
420  }
421 
422  if( hasImplicitDimension )
423  {
424  GEOSX_ERROR_IF_NE_MSG( permFromConduit[ NDIM ], NDIM,
425  "The permutation of the data in conduit and the provided Array don't match." );
426  }
427 
428  // Now pull out the dimensions and resize the array.
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();
432 
433  if( hasImplicitDimension )
434  {
435  GEOSX_ERROR_IF_NE( dims[ NDIM ], implicitDimensionLength );
436  }
437 
438  var.resize( NDIM, dims );
439 
440  // Finally memcpy
441  conduit::Node const & valuesNode = node.fetch_child( "__values__" );
442  localIndex numBytesFromArray = var.size() * sizeof( T );
443  GEOSX_ERROR_IF_NE( numBytesFromArray, valuesNode.dtype().strided_bytes() );
444  std::memcpy( var.data(), valuesNode.data_ptr(), numBytesFromArray );
445 }
446 
447 template< typename T >
448 void pushDataToConduitNode( InterObjectRelation< T > const & var,
449  conduit::Node & node )
450 {return pushDataToConduitNode( var.Base(), node ); }
451 
452 template< typename T >
453 void pullDataFromConduitNode( InterObjectRelation< T > & var,
454  conduit::Node const & node )
455 { return pullDataFromConduitNode( var.Base(), node ); }
456 
457 
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,
463  std::string const & fieldName,
464  std::string const & topology,
465  std::vector< std::string > const & componentNames )
466 {
467  GEOSX_ERROR_IF_LE( var.size(), 0 );
468 
469  using ConduitType = typename conduitTypeInfo< T >::type;
470  constexpr int conduitTypeID = conduitTypeInfo< T >::id;
471  constexpr int numComponentsPerValue = conduitTypeInfo< T >::numConduitValues;
472 
473  localIndex const totalNumberOfComponents = numComponentsPerValue * var.size() / var.size( 0 );
474  if( !componentNames.empty() )
475  {
476  GEOSX_ERROR_IF_NE( localIndex( componentNames.size() ), totalNumberOfComponents );
477  }
478 
479  var.move( LvArray::MemorySpace::CPU, false );
480 
481  conduit::DataType dtype( conduitTypeID, var.size( 0 ) );
482  dtype.set_stride( sizeof( ConduitType ) * numComponentsPerValue * var.strides()[ 0 ] );
483 
484  localIndex curComponent = 0;
485  LvArray::forValuesInSliceWithIndices( var[ 0 ], [&fields, &fieldName, &topology, &componentNames, totalNumberOfComponents, &dtype, &curComponent]
486  ( T const & val, auto const ... indices )
487  {
488  for( int i = 0; i < numComponentsPerValue; ++i )
489  {
490  std::string name;
491  if( totalNumberOfComponents == 1 )
492  {
493  name = fieldName;
494  }
495  else if( componentNames.empty() )
496  {
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;
502  }
503  else
504  {
505  name = componentNames[ curComponent++ ];
506  }
507 
508  conduit::Node & field = fields[ name ];
509  field[ "association" ] = "element";
510  field[ "volume_dependent" ] = "false";
511  field[ "topology" ] = topology;
512 
513  void const * pointer = internal::getPointerToComponent( val, i );
514  field[ "values" ].set_external( dtype, const_cast< void * >( pointer ) );
515  }
516  } );
517 }
518 
519 template< typename T >
520 void addBlueprintField( T const &,
521  conduit::Node & fields,
522  std::string const &,
523  std::string const &,
524  std::vector< std::string > const & )
525 {
526  GEOSX_ERROR( "Cannot create a mcarray out of " << LvArray::system::demangleType< T >() <<
527  "\nWas trying to write it to " << fields.path() );
528 }
529 
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 )
535 {
536  GEOSX_ERROR_IF_LE( var.size(), 0 );
537 
538  using ConduitType = typename conduitTypeInfo< T >::type;
539  constexpr int conduitTypeID = conduitTypeInfo< T >::id;
540  constexpr int numComponentsPerValue = conduitTypeInfo< T >::numConduitValues;
541 
542  if( !componentNames.empty() )
543  {
544  GEOSX_ERROR_IF_NE( localIndex( componentNames.size() ), numComponentsPerValue * var.size() / var.size( 0 ) );
545  }
546 
547  var.move( LvArray::MemorySpace::CPU, false );
548 
549  conduit::DataType dtype( conduitTypeID, var.size( 0 ) );
550  dtype.set_stride( sizeof( ConduitType ) * numComponentsPerValue * var.strides()[ 0 ] );
551 
552  localIndex curComponent = 0;
553  LvArray::forValuesInSliceWithIndices( var[ 0 ], [&componentNames, &node, &dtype, &curComponent]
554  ( T const & val, auto const ... indices )
555  {
556  for( int i = 0; i < numComponentsPerValue; ++i )
557  {
558  std::string const name = componentNames.empty() ? internal::getIndicesToComponent( val, i, indices ... ) :
559  componentNames[ curComponent++ ];
560 
561  void const * pointer = internal::getPointerToComponent( val, i );
562  node[ name ].set_external( dtype, const_cast< void * >( pointer ) );
563  }
564  } );
565 }
566 
567 template< typename T >
568 void populateMCArray( T const &,
569  conduit::Node & node,
570  std::vector< std::string > const & )
571 {
572  GEOSX_ERROR( "Cannot create a mcarray out of " << LvArray::system::demangleType< T >() <<
573  "\nWas trying to write it to " << node.path() );
574 }
575 
576 template< typename T, int NDIM, int USD >
577 std::enable_if_t< ( NDIM > 1 ) &&
578  ( std::is_arithmetic< T >::value ), // || traits::is_tensorT< T > ),
579  std::unique_ptr< Array< T, NDIM - 1 > > >
580 averageOverSecondDim( ArrayView< T const, NDIM, USD > const & var )
581 {
582  std::unique_ptr< Array< T, NDIM - 1 > > ret = std::make_unique< Array< T, NDIM - 1 > >();
583 
584  localIndex newDims[ NDIM - 1 ];
585  newDims[ 0 ] = var.size( 0 );
586  for( int i = 2; i < NDIM; ++i )
587  {
588  newDims[ i - 1 ] = var.size( i );
589  }
590 
591  ret->resize( NDIM - 1, newDims );
592 
593  ArrayView< T, NDIM - 1 > const & output = *ret;
594 
595  localIndex const numSamples = var.size( 1 );
596  forAll< serialPolicy >( var.size( 0 ), [var, numSamples, &output] ( localIndex const i )
597  {
598  LvArray::sumOverFirstDimension( var[ i ], output[ i ] );
599 
600  LvArray::forValuesInSlice( output[ i ], [numSamples] ( T & val )
601  {
602  val /= numSamples;
603  } );
604  } );
605 
606  return ret;
607 }
608 
609 template< typename T >
610 std::unique_ptr< int > averageOverSecondDim( T const & )
611 {
612  GEOSX_ERROR( "Cannot average over the second dimension of " << LvArray::system::demangleType< T >() );
613  return std::unique_ptr< int >( nullptr );
614 }
615 
616 
617 
618 template< bool DO_PACKING, typename T, typename IDX >
619 inline std::enable_if_t< bufferOps::is_packable_by_index< T >, localIndex >
620 PackByIndex( buffer_unit_type * & buffer, T & var, IDX & idx )
621 { return bufferOps::PackByIndex< DO_PACKING >( buffer, var, idx ); }
622 
623 template< bool DO_PACKING, typename T, typename IDX >
624 inline std::enable_if_t< !bufferOps::is_packable_by_index< T >, localIndex >
625 PackByIndex( buffer_unit_type * &, T &, IDX & )
626 { return 0; }
627 
628 template< typename T, typename IDX >
629 inline std::enable_if_t< bufferOps::is_packable_by_index< T >, localIndex >
630 UnpackByIndex( buffer_unit_type const * & buffer, T & var, IDX & idx )
631 { return bufferOps::UnpackByIndex( buffer, var, idx ); }
632 
633 template< typename T, typename IDX >
634 inline std::enable_if_t< !bufferOps::is_packable_by_index< T >, localIndex >
635 UnpackByIndex( buffer_unit_type const * &, T &, IDX & )
636 { return 0; }
637 
638 
639 template< bool DO_PACKING, typename T >
640 inline std::enable_if_t< bufferOps::is_container< T > || bufferOps::can_memcpy< T >, localIndex >
641 PackDevice( buffer_unit_type * & buffer, T const & var )
642 { return bufferOps::PackDevice< DO_PACKING >( buffer, var ); }
643 
644 
645 template< bool DO_PACKING, typename T >
646 inline std::enable_if_t< !bufferOps::is_container< T > && !bufferOps::can_memcpy< T >, localIndex >
647 PackDevice( buffer_unit_type * &, T const & )
648 {
649  GEOSX_ERROR( "Cannot pack " << LvArray::system::demangleType< T >() << " on device." );
650  return 0;
651 }
652 
653 template< bool DO_PACKING, typename T, typename IDX >
654 inline std::enable_if_t< bufferOps::is_container< T >, localIndex >
655 PackByIndexDevice( buffer_unit_type * & buffer, T const & var, IDX & idx )
656 { return bufferOps::PackByIndexDevice< DO_PACKING >( buffer, var, idx ); }
657 
658 template< bool DO_PACKING, typename T, typename IDX >
659 inline std::enable_if_t< !bufferOps::is_container< T >, localIndex >
660 PackByIndexDevice( buffer_unit_type * &, T const &, IDX & )
661 {
662  GEOSX_ERROR( "Trying to pack data type ("<<typeid(T).name()<<") on device but type is not packable by index." );
663  return 0;
664 }
665 
666 template< typename T >
667 inline std::enable_if_t< bufferOps::is_container< T >, localIndex >
668 UnpackDevice( buffer_unit_type const * & buffer, T const & var )
669 { return bufferOps::UnpackDevice( buffer, var ); }
670 
671 template< typename T >
672 inline std::enable_if_t< !bufferOps::is_container< T >, localIndex >
673 UnpackDevice( buffer_unit_type const * &, T const & )
674 { return 0; }
675 
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 ); }
680 
681 template< typename T, typename IDX >
682 inline std::enable_if_t< !bufferOps::is_container< T >, localIndex >
683 UnpackByIndexDevice( buffer_unit_type const * &, T &, IDX & )
684 { return 0; }
685 
686 
687 template< bool DO_PACKING, typename T >
689 PackDataDevice( buffer_unit_type * & buffer, T const & var )
690 { return bufferOps::PackDataDevice< DO_PACKING >( buffer, var ); }
691 
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 ); }
696 
697 template< bool DO_PACKING, typename T, typename IDX >
698 inline std::enable_if_t< !bufferOps::is_container< T >, localIndex >
699 PackDataByIndexDevice( buffer_unit_type * &, T const &, IDX & )
700 {
701  GEOSX_ERROR( "Trying to pack data type ("<<typeid(T).name()<<") on device but type is not packable by index." );
702  return 0;
703 }
704 
705 template< typename T >
706 inline std::enable_if_t< bufferOps::is_container< T >, localIndex >
707 UnpackDataDevice( buffer_unit_type const * & buffer, T const & var )
708 { return bufferOps::UnpackDataDevice( buffer, var ); }
709 
710 template< typename T >
711 inline std::enable_if_t< !bufferOps::is_container< T >, localIndex >
712 UnpackDataDevice( buffer_unit_type const * &, T const & )
713 { return 0; }
714 
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 ); }
719 
720 template< typename T, typename IDX >
721 inline std::enable_if_t< !bufferOps::is_container< T >, localIndex >
722 UnpackDataByIndexDevice( buffer_unit_type const * &, T const &, IDX & )
723 { return 0; }
724 
725 } // namespace WrapperHelpers
726 } // namespace dataRepository
727 } // namespace geosx
728 
729 #undef RESTART_TYPE_LOGGING
730 
731 #endif // GEOSX_DATAREPOSITORY_WRAPPERHELPERS_HPP_
LvArray::ArrayView< T, NDIM, USD, localIndex, LvArray::ChaiBuffer > ArrayView
Multidimensional array view type. See LvArray:ArrayView for details.
Definition: DataTypes.hpp:175
std::string getIndexString()
Definition: indexing.hpp:131
std::string demangleType()
Definition: system.hpp:50
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.
Definition: DataTypes.hpp:193
double real64
64-bit floating point type.
Definition: DataTypes.hpp:136
#define GEOSX_ERROR_IF_GE(lhs, rhs)
Raise a hard error if one value compares greater than or equal to the other.
Definition: Logger.hpp:209
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.
Definition: Logger.hpp:179
#define GEOSX_ERROR_IF_LE(lhs, rhs)
Raise a hard error if one value compares less than or equal to the other.
Definition: Logger.hpp:239
signed char buffer_unit_type
Type stored in communication buffers.
Definition: DataTypes.hpp:146
#define GEOSX_LOG(...)
Log a message on screen.
Definition: Logger.hpp:35
MemorySpace
An enum containing the available memory spaces.
#define GEOSX_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:110
#define GEOSX_DEBUG_VAR(...)
Mark a debug variable and silence compiler warnings.
Definition: GeosxMacros.hpp:81
LvArray::Array< T, NDIM, PERMUTATION, localIndex, LvArray::ChaiBuffer > Array
Multidimensional array type. See LvArray:Array for details.
Definition: DataTypes.hpp:169
std::ptrdiff_t localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
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.
Definition: DataTypes.hpp:131
#define GEOSX_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:66
#define GEOSX_ERROR_IF_NE_MSG(lhs, rhs, msg)
Raise a hard error if two values are not equal.
Definition: Logger.hpp:172