LvArray
ArrayOfArraysView.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors.
3  * All rights reserved.
4  * See the LICENSE file for details.
5  * SPDX-License-Identifier: (BSD-3-Clause)
6  */
7 
13 #pragma once
14 
15 // Source includes
16 #include "bufferManipulation.hpp"
17 #include "arrayManipulation.hpp"
19 #include "ArraySlice.hpp"
20 #include "typeManipulation.hpp"
21 #include "math.hpp"
22 #include "umpireInterface.hpp"
23 
24 // TPL includes
25 #include <RAJA/RAJA.hpp>
26 
27 // System includes
28 #include <cstring>
29 
30 #ifdef LVARRAY_BOUNDS_CHECK
31 
37 #define ARRAYOFARRAYS_CHECK_BOUNDS( i ) \
38  LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size(), \
39  "Bounds Check Failed: i=" << i << " size()=" << this->size() )
40 
47 #define ARRAYOFARRAYS_CHECK_BOUNDS2( i, j ) \
48  LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size() || \
49  !arrayManipulation::isPositive( j ) || j >= this->m_sizes[ i ], \
50  "Bounds Check Failed: i=" << i << " size()=" << this->size() << \
51  " j=" << j << " m_sizes[ i ]=" << this->m_sizes[ i ] )
52 
58 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS( i ) \
59  LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i > this->size(), \
60  "Insert Bounds Check Failed: i=" << i << " size()=" << this->size() )
61 
68 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j ) \
69  LVARRAY_ERROR_IF( !arrayManipulation::isPositive( i ) || i >= this->size() || \
70  !arrayManipulation::isPositive( j ) || j > this->sizeOfArray( i ), \
71  "Insert Bounds Check Failed: i=" << i << " size()=" << this->size() << \
72  " j=" << j << " sizeOfArray( i )=" << this->sizeOfArray( i ) )
73 
80 #define ARRAYOFARRAYS_CAPACITY_CHECK( i, increase ) \
81  LVARRAY_ERROR_IF( this->sizeOfArray( i ) + increase > this->capacityOfArray( i ), \
82  "Capacity Check Failed: i=" << i << " increase=" << increase << \
83  " sizeOfArray( i )=" << this->sizeOfArray( i ) << " capacityOfArray( i )=" << \
84  this->capacityOfArray( i ) )
85 
93 #define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, increase ) \
94  LVARRAY_ERROR_IF( previousSize + increase > this->capacityOfArray( i ), \
95  "Capacity Check Failed: i=" << i << " increase=" << increase << \
96  " sizeOfArray( i )=" << previousSize << " capacityOfArray( i )=" << \
97  this->capacityOfArray( i ) )
98 
99 #else // LVARRAY_BOUNDS_CHECK
100 
106 #define ARRAYOFARRAYS_CHECK_BOUNDS( i )
107 
114 #define ARRAYOFARRAYS_CHECK_BOUNDS2( i, j )
115 
121 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS( i )
122 
129 #define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2( i, j )
130 
137 #define ARRAYOFARRAYS_CAPACITY_CHECK( i, increase )
138 
146 #define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, increase )
147 
148 #endif // LVARRAY_BOUNDS_CHECK
149 
150 namespace LvArray
151 {
152 
166 template< typename T,
167  typename INDEX_TYPE,
168  bool CONST_SIZES,
169  template< typename > class BUFFER_TYPE >
171 {
172 protected:
174  using INDEX_TYPE_NC = std::remove_const_t< INDEX_TYPE >;
175 
177  using SIZE_TYPE = std::conditional_t< CONST_SIZES, INDEX_TYPE const, INDEX_TYPE_NC >;
178 
179 public:
180  static_assert( !std::is_const< T >::value || (std::is_const< INDEX_TYPE >::value && CONST_SIZES),
181  "When T is const INDEX_TYPE must also be const and CONST_SIZES must be true" );
182  static_assert( std::is_integral< INDEX_TYPE >::value, "INDEX_TYPE must be integral." );
183 
185  using ValueType = T;
186 
188  using IndexType = INDEX_TYPE;
189 
191  using value_type = T;
192 
194  using size_type = INDEX_TYPE;
195 
199 
205  ArrayOfArraysView() = default;
206 
211  ArrayOfArraysView( ArrayOfArraysView const & ) = default;
212 
217  LVARRAY_HOST_DEVICE constexpr inline
219  m_numArrays( src.m_numArrays ),
220  m_offsets( std::move( src.m_offsets ) ),
221  m_sizes( std::move( src.m_sizes ) ),
222  m_values( std::move( src.m_values ) )
223  { src.m_numArrays = 0; }
224 
232  LVARRAY_HOST_DEVICE constexpr inline
233  ArrayOfArraysView( INDEX_TYPE const numArrays,
234  BUFFER_TYPE< INDEX_TYPE > const & offsets,
235  BUFFER_TYPE< SIZE_TYPE > const & sizes,
236  BUFFER_TYPE< T > const & values ):
237  m_numArrays( numArrays ),
238  m_offsets( offsets ),
239  m_sizes( sizes ),
240  m_values( values )
241  {}
242 
247  inline
248  ArrayOfArraysView & operator=( ArrayOfArraysView const & ) = default;
249 
255  inline
257  {
258  m_numArrays = src.m_numArrays;
259  src.m_numArrays = 0;
260  m_offsets = std::move( src.m_offsets );
261  m_sizes = std::move( src.m_sizes );
262  m_values = std::move( src.m_values );
263  return *this;
264  }
265 
267 
271 
276  LVARRAY_HOST_DEVICE constexpr inline
278  toView() const
279  {
281  this->m_offsets,
282  this->m_sizes,
283  this->m_values );
284  }
285 
289  LVARRAY_HOST_DEVICE constexpr inline
292  {
294  this->m_offsets,
295  this->m_sizes,
296  this->m_values );
297  }
298 
302  LVARRAY_HOST_DEVICE constexpr inline
304  toViewConst() const
305  {
307  this->m_offsets,
308  this->m_sizes,
309  this->m_values );
310  }
311 
313 
317 
322  LVARRAY_HOST_DEVICE constexpr inline
324  { return m_numArrays; }
325 
331  INDEX_TYPE_NC sizeOfArray( INDEX_TYPE const i ) const
332  {
334  return m_sizes[ i ];
335  }
336 
340  LVARRAY_HOST_DEVICE constexpr inline
341  SIZE_TYPE const * getSizes() const
342  {
343  return m_sizes.data();
344  }
345 
346 
351  LVARRAY_HOST_DEVICE constexpr inline
352  INDEX_TYPE const * getOffsets() const
353  {
354  return m_offsets.data();
355  }
356 
360  LVARRAY_HOST_DEVICE constexpr inline
361  T const * getValues() const
362  {
363  return m_values.data();
364  }
365 
366 
367 
373  {
374  LVARRAY_ASSERT( m_sizes.capacity() < m_offsets.capacity());
375  return m_sizes.capacity();
376  }
377 
383  INDEX_TYPE_NC capacityOfArray( INDEX_TYPE const i ) const
384  {
386  return m_offsets[ i + 1 ] - m_offsets[ i ];
387  }
388 
392  LVARRAY_HOST_DEVICE constexpr inline
394  { return m_values.capacity(); }
395 
397 
401 
409  {
411  return ArraySlice< T, 1, 0, INDEX_TYPE_NC >( m_values.data() + m_offsets[ i ], &m_sizes[ i ], nullptr );
412  }
413 
420  T & operator()( INDEX_TYPE const i, INDEX_TYPE const j ) const
421  {
423  return m_values[m_offsets[ i ] + j];
424  }
425 
427 
431 
441  template< typename ... ARGS >
442  LVARRAY_HOST_DEVICE inline
443  void emplaceBack( INDEX_TYPE const i, ARGS && ... args ) const
444  {
447 
448  T * const ptr = m_values.data() + m_offsets[ i ];
449  arrayManipulation::emplaceBack( ptr, sizeOfArray( i ), std::forward< ARGS >( args ) ... );
450  m_sizes[ i ] += 1;
451  }
452 
462  template< typename POLICY, typename ... ARGS >
463  LVARRAY_HOST_DEVICE inline
464  void emplaceBackAtomic( INDEX_TYPE const i, ARGS && ... args ) const
465  {
467 
468  T * const ptr = m_values.data() + m_offsets[ i ];
469  INDEX_TYPE const previousSize = RAJA::atomicInc< POLICY >( &m_sizes[ i ] );
470  ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, 1 );
471 
472  arrayManipulation::emplaceBack( ptr, previousSize, std::forward< ARGS >( args ) ... );
473  }
474 
484  template< typename ITER >
485  LVARRAY_HOST_DEVICE inline
486  void appendToArray( INDEX_TYPE const i, ITER const first, ITER const last ) const
487  {
489 
490  T * const ptr = m_values.data() + m_offsets[ i ];
491  INDEX_TYPE const n = arrayManipulation::append( ptr, sizeOfArray( i ), first, last );
493  m_sizes[ i ] += n;
494  }
495 
505  template< typename ... ARGS >
506  LVARRAY_HOST_DEVICE inline
507  void emplace( INDEX_TYPE const i, INDEX_TYPE const j, ARGS && ... args ) const
508  {
511 
512  T * const ptr = m_values.data() + m_offsets[ i ];
513  arrayManipulation::emplace( ptr, sizeOfArray( i ), j, std::forward< ARGS >( args )... );
514  m_sizes[ i ]++;
515  }
516 
527  template< typename ITER >
528  LVARRAY_HOST_DEVICE inline
529  void insertIntoArray( INDEX_TYPE const i,
530  INDEX_TYPE const j,
531  ITER const first,
532  ITER const last ) const
533  {
535  INDEX_TYPE const n = arrayManipulation::iterDistance( first, last );
537 
538  T * const ptr = m_values.data() + m_offsets[ i ];
539  arrayManipulation::insert( ptr, sizeOfArray( i ), j, first, n );
540  m_sizes[ i ] += n;
541  }
542 
549  LVARRAY_HOST_DEVICE inline
550  void eraseFromArray( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const n=1 ) const
551  {
553 
554  T * const ptr = m_values.data() + m_offsets[ i ];
555  arrayManipulation::erase( ptr, sizeOfArray( i ), j, n );
556  m_sizes[ i ] -= n;
557  }
558 
560 
564 
570  void registerTouch( MemorySpace const space ) const
571  {
572  m_values.registerTouch( space );
573  m_sizes.registerTouch( space );
574  m_offsets.registerTouch( space );
575  }
576 
583  void move( MemorySpace const space, bool touch=true ) const
584  {
585  m_values.move( space, touch );
586  m_sizes.move( space, touch );
587 
588  #if defined(LVARRAY_USE_CUDA)
589  if( space == MemorySpace::cuda ) touch = false;
590  #endif
591  m_offsets.move( space, touch );
592  }
593 
594 
596 
597 protected:
598 
603  template< typename U >
604  using PairOfBuffers = std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U > const & >;
605 
611  m_numArrays( 0 ),
612  m_offsets( true ),
613  m_sizes( true ),
614  m_values( true )
615  {}
616 
620 
627  void resize( INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity=0 )
628  { return resizeImpl( newSize, defaultArrayCapacity ); }
629 
634  void reserve( INDEX_TYPE const newCapacity )
635  {
636  bufferManipulation::reserve( m_offsets, m_numArrays + 1, MemorySpace::host, newCapacity + 1 );
637  bufferManipulation::reserve( m_sizes, m_numArrays, MemorySpace::host, newCapacity );
638  }
639 
647  template< class ... BUFFERS >
648  void reserveValues( INDEX_TYPE const newValueCapacity, BUFFERS & ... buffers )
649  {
650  INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ];
651  typeManipulation::forEachArg( [newValueCapacity, maxOffset] ( auto & buffer )
652  {
653  bufferManipulation::reserve( buffer, maxOffset, MemorySpace::host, newValueCapacity );
654  }, m_values, buffers ... );
655  }
656 
664  template< class ... BUFFERS >
665  void compress( BUFFERS & ... buffers )
666  {
667  if( m_numArrays == 0 ) return;
668 
669  for( INDEX_TYPE i = 0; i < m_numArrays - 1; ++i )
670  {
671  INDEX_TYPE const nextOffset = m_offsets[ i + 1 ];
672  INDEX_TYPE const shiftAmount = nextOffset - m_offsets[ i ] - sizeOfArray( i );
673  INDEX_TYPE const sizeOfNextArray = sizeOfArray( i + 1 );
674 
675  // Shift the values in the next array down.
677  [sizeOfNextArray, nextOffset, shiftAmount] ( auto & buffer )
678  {
679  arrayManipulation::uninitializedShiftDown( &buffer[ nextOffset ], sizeOfNextArray, shiftAmount );
680  }, m_values, buffers ... );
681 
682  // And update the offsets.
683  m_offsets[ i + 1 ] -= shiftAmount;
684  }
685 
686  // Update the last offset.
687  m_offsets[ m_numArrays ] = m_offsets[ m_numArrays - 1 ] + sizeOfArray( m_numArrays - 1 );
688  }
689 
697  template< typename ... BUFFERS >
698  void resizeFromOffsets( INDEX_TYPE const numSubArrays,
699  INDEX_TYPE const * const offsets,
700  BUFFERS & ... buffers )
701  {
702  auto const fillOffsets = [&]()
703  {
705  offsets + numSubArrays + 1,
706  m_offsets.data() );
707  };
708  resizeFromOffsetsImpl( numSubArrays, fillOffsets, buffers ... );
709  }
710 
720  template< typename POLICY, typename ... BUFFERS >
721  void resizeFromCapacities( INDEX_TYPE const numSubArrays,
722  INDEX_TYPE const * const capacities,
723  BUFFERS & ... buffers )
724  {
725  auto const fillOffsets = [&]()
726  {
727  m_offsets[ 0 ] = 0;
728 // RAJA::inclusive_scan< POLICY >( capacities,
729 // capacities + numSubArrays,
730 // m_offsets.data() + 1 );
731 
732  RAJA::inclusive_scan< POLICY >( RAJA::make_span< INDEX_TYPE const * >( capacities, numSubArrays ),
733  RAJA::make_span< INDEX_TYPE * >( m_offsets.data()+1, numSubArrays ) );
734  };
735  resizeFromOffsetsImpl( numSubArrays, fillOffsets, buffers ... );
736  }
737 
739 
743 
750  { *this = std::move( src ); }
751 
758  template< typename ... BUFFERS >
759  void resizeImpl( INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity, BUFFERS & ... buffers )
760  {
762 
763  INDEX_TYPE const offsetsSize = ( m_numArrays == 0 ) ? 0 : m_numArrays + 1;
764 
765  if( newSize < m_numArrays )
766  {
767  destroyValues( newSize, m_numArrays, buffers ... );
768  bufferManipulation::resize( m_offsets, offsetsSize, newSize + 1, 0 );
770  }
771  else
772  {
773  // The ternary here accounts for the case where m_offsets hasn't been allocated yet (when calling from a
774  // constructor).
775  INDEX_TYPE const originalOffset = (m_numArrays == 0) ? 0 : m_offsets[m_numArrays];
776  bufferManipulation::resize( m_offsets, offsetsSize, newSize + 1, originalOffset );
778 
779  if( defaultArrayCapacity > 0 )
780  {
781  for( INDEX_TYPE i = 1; i < newSize + 1 - m_numArrays; ++i )
782  {
783  m_offsets[ m_numArrays + i ] = originalOffset + i * defaultArrayCapacity;
784  }
785 
786  INDEX_TYPE const totalSize = m_offsets[ newSize ];
787 
788  INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ];
789  typeManipulation::forEachArg( [totalSize, maxOffset]( auto & buffer )
790  {
791  bufferManipulation::reserve( buffer, maxOffset, MemorySpace::host, totalSize );
792  }, m_values, buffers ... );
793  }
794  }
795 
796  m_numArrays = newSize;
797  }
798 
805  template< class ... BUFFERS >
806  void free( BUFFERS & ... buffers )
807  {
808  destroyValues( 0, m_numArrays, buffers ... );
809 
810  typeManipulation::forEachArg( []( auto & buffer )
811  {
812  buffer.free();
813  }, m_sizes, m_offsets, m_values, buffers ... );
814 
815  m_numArrays = 0;
816  }
817 
829  template< class ... PAIRS_OF_BUFFERS >
830  void setEqualTo( INDEX_TYPE const srcNumArrays,
831  INDEX_TYPE const srcMaxOffset,
832  BUFFER_TYPE< INDEX_TYPE > const & srcOffsets,
833  BUFFER_TYPE< INDEX_TYPE > const & srcSizes,
834  BUFFER_TYPE< T > const & srcValues,
835  PAIRS_OF_BUFFERS && ... pairs )
836  {
837  destroyValues( 0, m_numArrays, pairs.first ... );
838 
839  INDEX_TYPE const offsetsSize = ( m_numArrays == 0 ) ? 0 : m_numArrays + 1;
840 
841  bufferManipulation::copyInto( m_offsets, offsetsSize, srcOffsets, srcNumArrays + 1 );
842  bufferManipulation::copyInto( m_sizes, m_numArrays, srcSizes, srcNumArrays );
843 
844  INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ];
845  typeManipulation::forEachArg( [maxOffset, srcMaxOffset]( auto & dstBuffer )
846  {
847  bufferManipulation::reserve( dstBuffer, maxOffset, MemorySpace::host, srcMaxOffset );
848  }, m_values, pairs.first ... );
849 
850  m_numArrays = srcNumArrays;
851 
852  typeManipulation::forEachArg( [this] ( auto & pair )
853  {
854  auto & dstBuffer = pair.first;
855  auto const & srcBuffer = pair.second;
856 
857  for( INDEX_TYPE_NC i = 0; i < m_numArrays; ++i )
858  {
859  INDEX_TYPE const offset = m_offsets[ i ];
860  INDEX_TYPE const arraySize = sizeOfArray( i );
861  arrayManipulation::uninitializedCopy( &srcBuffer[ offset ],
862  &srcBuffer[ offset ] + arraySize,
863  &dstBuffer[ offset ] );
864  }
865  }, PairOfBuffers< T >( m_values, srcValues ), pairs ... );
866  }
867 
876  template< class ... BUFFERS >
877  void setCapacityOfArray( INDEX_TYPE const i, INDEX_TYPE const newCapacity, BUFFERS & ... buffers )
878  {
881 
882  INDEX_TYPE const arrayCapacity = capacityOfArray( i );
883  INDEX_TYPE const capacityIncrease = newCapacity - arrayCapacity;
884  if( capacityIncrease == 0 ) return;
885 
886  if( capacityIncrease > 0 )
887  {
888  INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ];
890  [this, i, maxOffset, capacityIncrease]( auto & buffer )
891  {
892  // Increase the size of the buffer.
893  bufferManipulation::dynamicReserve( buffer, maxOffset, maxOffset + capacityIncrease );
894 
895  // Shift up the values.
896  for( INDEX_TYPE array = m_numArrays - 1; array > i; --array )
897  {
898  INDEX_TYPE const curArraySize = sizeOfArray( array );
899  INDEX_TYPE const curArrayOffset = m_offsets[ array ];
900  arrayManipulation::uninitializedShiftUp( &buffer[ curArrayOffset ], curArraySize, capacityIncrease );
901  }
902  },
903  m_values, buffers ...
904  );
905  }
906  else
907  {
908  INDEX_TYPE const arrayOffset = m_offsets[ i ];
909  INDEX_TYPE const capacityDecrease = -capacityIncrease;
910 
911  INDEX_TYPE const prevArraySize = sizeOfArray( i );
912  INDEX_TYPE const newArraySize = math::min( prevArraySize, newCapacity );
913 
914  m_sizes[ i ] = newArraySize;
916  [this, i, capacityDecrease, arrayOffset, newArraySize, prevArraySize] ( auto & buffer )
917  {
918  // Delete the values at the end of the array.
919  arrayManipulation::destroy( &buffer[ arrayOffset + newArraySize ], prevArraySize - newArraySize );
920 
921  // Shift down the values of subsequent arrays.
922  for( INDEX_TYPE array = i + 1; array < m_numArrays; ++array )
923  {
924  INDEX_TYPE const curArraySize = sizeOfArray( array );
925  INDEX_TYPE const curArrayOffset = m_offsets[array];
926  arrayManipulation::uninitializedShiftDown( &buffer[ curArrayOffset ], curArraySize, capacityDecrease );
927  }
928  },
929  m_values, buffers ...
930  );
931  }
932 
933  // Update the offsets array
934  for( INDEX_TYPE array = i + 1; array < m_numArrays + 1; ++array )
935  {
936  m_offsets[array] += capacityIncrease;
937  }
938 
939  // We need to touch the offsets on the CPU because since it contains const data
940  // when the ArrayOfArraysView gets copy constructed it doesn't get touched even though
941  // it can then be modified via this method when called from a parent non-view class.
942  m_offsets.registerTouch( MemorySpace::host );
943  }
944 
950  template< typename U >
951  void setName( std::string const & name )
952  {
953  m_offsets.template setName< U >( name + "/m_offsets" );
954  m_sizes.template setName< U >( name + "/m_sizes" );
955  m_values.template setName< U >( name + "/m_values" );
956  }
957 
959 
962 
965  BUFFER_TYPE< INDEX_TYPE > m_offsets;
966 
968  BUFFER_TYPE< SIZE_TYPE > m_sizes;
969 
972  BUFFER_TYPE< T > m_values;
973 
974 private:
975 
986  template< class ... BUFFERS >
987  void destroyValues( INDEX_TYPE const begin, INDEX_TYPE const end, BUFFERS & ... buffers )
988  {
991 
992  // If the values aren't trivially destructable then the data needs to be moved back to the host.
993  // This moves m_sizes and m_offsets, m_values and buffers are moved inside the loop.
994  if( !typeManipulation::all_of_t< std::is_trivially_destructible< T >,
995  std::is_trivially_destructible< typename BUFFERS::value_type > ... >::value )
996  { move( MemorySpace::host, true ); }
997 
998  typeManipulation::forEachArg( [this, begin, end] ( auto & buffer )
999  {
1000  if( !std::is_trivially_destructible< std::remove_reference_t< decltype( buffer[ 0 ] ) > >::value )
1001  {
1002  buffer.move( MemorySpace::host, true );
1003  for( INDEX_TYPE i = begin; i < end; ++i )
1004  {
1005  INDEX_TYPE const offset = m_offsets[ i ];
1006  INDEX_TYPE const arraySize = sizeOfArray( i );
1007  arrayManipulation::destroy( &buffer[ offset ], arraySize );
1008  }
1009  }
1010  }, m_values, buffers ... );
1011  }
1012 
1020  template< typename FUNC, typename ... BUFFERS >
1021  void resizeFromOffsetsImpl( INDEX_TYPE const numSubArrays,
1022  FUNC && fillOffsets,
1023  BUFFERS & ... buffers )
1024  {
1025  LVARRAY_ASSERT( arrayManipulation::isPositive( numSubArrays ) );
1026 
1027  destroyValues( 0, m_numArrays, buffers ... );
1028 
1029  bufferManipulation::reserve( m_sizes, m_numArrays, MemorySpace::host, numSubArrays );
1030  umpireInterface::memset( m_sizes.data(), 0, m_sizes.capacity() * sizeof( INDEX_TYPE ) );
1031 
1032  INDEX_TYPE const offsetsSize = ( m_numArrays == 0 ) ? 0 : m_numArrays + 1;
1033  bufferManipulation::reserve( m_offsets, offsetsSize, MemorySpace::host, numSubArrays + 1 );
1034 
1035  fillOffsets();
1036  LVARRAY_ASSERT_EQ( m_offsets[0], 0 );
1037  LVARRAY_ASSERT( sortedArrayManipulation::isSorted( m_offsets.data(), m_offsets.data() + numSubArrays + 1 ) );
1038 
1039  m_numArrays = numSubArrays;
1040  INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ];
1041  typeManipulation::forEachArg( [ maxOffset ] ( auto & buffer )
1042  {
1043  bufferManipulation::reserve( buffer, 0, MemorySpace::host, maxOffset );
1044  }, m_values, buffers ... );
1045  }
1046 };
1047 
1048 } /* namespace LvArray */
#define ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK(i, previousSize, increase)
Check that the capacity of array i isn&#39;t exceeded when the size is increased by increase.
Definition: ArrayOfArraysView.hpp:146
LVARRAY_HOST_DEVICE void resize(BUFFER &buf, std::ptrdiff_t const size, std::ptrdiff_t const newSize, ARGS &&... args)
Resize the buffer to the given size.
Definition: bufferManipulation.hpp:272
#define LVARRAY_ASSERT(EXP)
Assert EXP is true with no message.
Definition: Macros.hpp:184
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, BUFFER_TYPE > toView() const
Definition: ArrayOfArraysView.hpp:278
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE std::ptrdiff_t append(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, ITER first, ITER const last)
Append the given values to the array.
Definition: arrayManipulation.hpp:447
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK ArraySlice< T, 1, 0, INDEX_TYPE_NC > operator[](INDEX_TYPE const i) const
Definition: ArrayOfArraysView.hpp:408
#define ARRAYOFARRAYS_CHECK_BOUNDS(i)
Check that i is a valid array index.
Definition: ArrayOfArraysView.hpp:106
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void emplaceBack(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, ARGS &&... args)
Append the to the array constructing the new value in place.
Definition: arrayManipulation.hpp:425
INDEX_TYPE size_type
The integer type used for indexing, here for stl compatability.
Definition: ArrayOfArraysView.hpp:194
void destroyValues(INDEX_TYPE const begin, INDEX_TYPE const end, BUFFERS &... buffers)
Destroy the values in arrays in the range [begin, end).
Definition: ArrayOfArraysView.hpp:987
void reserve(INDEX_TYPE const newCapacity)
Reserve space for the given number of arrays.
Definition: ArrayOfArraysView.hpp:634
This class serves to provide a sliced multidimensional interface to the family of LvArray classes...
Definition: ArraySlice.hpp:89
INDEX_TYPE IndexType
The integer type used for indexing.
Definition: ArrayOfArraysView.hpp:188
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void insert(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, ITERATOR first, std::ptrdiff_t const n)
Insert the given values into the array at the given position.
Definition: arrayManipulation.hpp:505
BUFFER_TYPE< INDEX_TYPE > m_offsets
Definition: ArrayOfArraysView.hpp:965
ArrayOfArraysView()=default
A constructor to create an uninitialized ArrayOfArraysView.
LVARRAY_HOST_DEVICE CONSTEXPR_WITH_NDEBUG INDEX_TYPE_NC capacity() const
Definition: ArrayOfArraysView.hpp:372
void dynamicReserve(BUFFER &buf, std::ptrdiff_t const size, std::ptrdiff_t const newCapacity)
If the buffer&#39;s capacity is greater than newCapacity this is a no-op. Otherwise the buffer&#39;s capacity...
Definition: bufferManipulation.hpp:251
BUFFER_TYPE< T > m_values
Definition: ArrayOfArraysView.hpp:972
void move(MemorySpace const space, bool touch=true) const
Move this ArrayOfArrays to the given memory space.
Definition: ArrayOfArraysView.hpp:583
LVARRAY_HOST_DEVICE void emplaceBack(INDEX_TYPE const i, ARGS &&... args) const
Append a value to an array.
Definition: ArrayOfArraysView.hpp:443
Contains templates useful for type manipulation.
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView(INDEX_TYPE const numArrays, BUFFER_TYPE< INDEX_TYPE > const &offsets, BUFFER_TYPE< SIZE_TYPE > const &sizes, BUFFER_TYPE< T > const &values)
Construct a new ArrayOfArraysView from the given buffers.
Definition: ArrayOfArraysView.hpp:233
ArrayOfArraysView & operator=(ArrayOfArraysView &&src)
Move assignment operator..
Definition: ArrayOfArraysView.hpp:256
BUFFER_TYPE< SIZE_TYPE > m_sizes
Holds the size of each array.
Definition: ArrayOfArraysView.hpp:968
LVARRAY_HOST_DEVICE void appendToArray(INDEX_TYPE const i, ITER const first, ITER const last) const
Append values to an array.
Definition: ArrayOfArraysView.hpp:486
LVARRAY_HOST_DEVICE constexpr T const * getValues() const
Definition: ArrayOfArraysView.hpp:361
#define ARRAYOFARRAYS_CHECK_BOUNDS2(i, j)
Check that i is a valid array index and that j is a valid index into that array.
Definition: ArrayOfArraysView.hpp:114
LVARRAY_HOST_DEVICE constexpr bool isSorted(Description const desc)
Definition: sortedArrayManipulation.hpp:55
COL_TYPE value_type
An alias for the type contained in the inner arrays, here for stl compatability.
Definition: ArrayOfArraysView.hpp:191
Contains the LvArray umpire interface. This is only used to keep umpire/ResourceManager.hpp out of the includes for most headers.
void compress(BUFFERS &... buffers)
Compress the arrays so that the values of each array are contiguous with no extra capacity in between...
Definition: ArrayOfArraysView.hpp:665
LVARRAY_HOST_DEVICE constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > min(T const a, T const b)
Definition: math.hpp:358
LVARRAY_HOST_DEVICE void emplace(INDEX_TYPE const i, INDEX_TYPE const j, ARGS &&... args) const
Insert a value into an array.
Definition: ArrayOfArraysView.hpp:507
#define CONSTEXPR_WITHOUT_BOUNDS_CHECK
Expands to constexpr when array bound checking is disabled.
Definition: Macros.hpp:609
LVARRAY_HOST_DEVICE constexpr std::enable_if< std::is_signed< INDEX_TYPE >::value, bool >::type isPositive(INDEX_TYPE const i)
Definition: arrayManipulation.hpp:82
ArrayOfArraysView & operator=(ArrayOfArraysView const &)=default
Default copy assignment operator.
void resize(INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity=0)
Set the number of arrays.
Definition: ArrayOfArraysView.hpp:627
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void erase(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, std::ptrdiff_t const n=1)
Shift the values in the array at or above the given position down by the given amount overwriting the...
Definition: arrayManipulation.hpp:396
Contains the implementation of LvArray::ArraySlice.
void setName(std::string const &name)
Set the name to be displayed whenever the underlying Buffer&#39;s user call back is called.
Definition: ArrayOfArraysView.hpp:951
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK T & operator()(INDEX_TYPE const i, INDEX_TYPE const j) const
Definition: ArrayOfArraysView.hpp:420
This class provides a view into an array of arrays like object.
Definition: ArrayOfArraysView.hpp:170
#define ARRAYOFARRAYS_CAPACITY_CHECK(i, increase)
Check that the capacity of array i isn&#39;t exceeded when the size is increased by increase.
Definition: ArrayOfArraysView.hpp:137
DISABLE_HD_WARNING constexpr LVARRAY_HOST_DEVICE void forEachArg(F &&f)
The recursive base case where no argument is provided.
Definition: typeManipulation.hpp:129
LVARRAY_HOST_DEVICE constexpr INDEX_TYPE_NC valueCapacity() const
Definition: ArrayOfArraysView.hpp:393
Contains functions for manipulating buffers.
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK INDEX_TYPE_NC sizeOfArray(INDEX_TYPE const i) const
Definition: ArrayOfArraysView.hpp:331
Contains some portable math functions.
void resizeImpl(INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity, BUFFERS &... buffers)
Set the number of arrays.
Definition: ArrayOfArraysView.hpp:759
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void uninitializedCopy(ITER first, ITER const &last, T *LVARRAY_RESTRICT dst)
Copy construct values from the source to the destination.
Definition: arrayManipulation.hpp:177
#define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS(i)
Check that i is a valid index to insert an array at.
Definition: ArrayOfArraysView.hpp:121
camp::resources::Platform MemorySpace
an alias for camp::resources::Platform.
Definition: bufferManipulation.hpp:31
Contains functions for manipulating a contiguous array of values.
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView< T, INDEX_TYPE const, true, BUFFER_TYPE > toViewConstSizes() const
Definition: ArrayOfArraysView.hpp:291
LVARRAY_HOST_DEVICE void emplaceBackAtomic(INDEX_TYPE const i, ARGS &&... args) const
Append a value to an array in a thread safe manner.
Definition: ArrayOfArraysView.hpp:464
The top level namespace.
Definition: Array.hpp:24
void resizeFromOffsetsImpl(INDEX_TYPE const numSubArrays, FUNC &&fillOffsets, BUFFERS &... buffers)
Clears the array and creates a new array with the given number of sub-arrays.
Definition: ArrayOfArraysView.hpp:1021
LVARRAY_HOST_DEVICE void reserve(BUFFER &buf, std::ptrdiff_t const size, MemorySpace const space, std::ptrdiff_t const newCapacity)
Reserve space in the buffer for at least the given capacity.
Definition: bufferManipulation.hpp:230
This file contains common sorted array manipulation routines. Aside from the functions that take a ca...
void resizeFromCapacities(INDEX_TYPE const numSubArrays, INDEX_TYPE const *const capacities, BUFFERS &... buffers)
Clears the array and creates a new array with the given number of sub-arrays.
Definition: ArrayOfArraysView.hpp:721
void setEqualTo(INDEX_TYPE const srcNumArrays, INDEX_TYPE const srcMaxOffset, BUFFER_TYPE< INDEX_TYPE > const &srcOffsets, BUFFER_TYPE< INDEX_TYPE > const &srcSizes, BUFFER_TYPE< T > const &srcValues, PAIRS_OF_BUFFERS &&... pairs)
Set this ArrayOfArraysView equal to the provided arrays.
Definition: ArrayOfArraysView.hpp:830
INDEX_TYPE_NC m_numArrays
The number of arrays contained.
Definition: ArrayOfArraysView.hpp:961
ArrayOfArraysView(bool)
Protected constructor to be used by parent classes.
Definition: ArrayOfArraysView.hpp:610
void free(BUFFERS &... buffers)
Destroy all the objects held by this array and free all associated memory.
Definition: ArrayOfArraysView.hpp:806
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void destroy(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size)
Destory the values in the array.
Definition: arrayManipulation.hpp:152
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK INDEX_TYPE_NC capacityOfArray(INDEX_TYPE const i) const
Definition: ArrayOfArraysView.hpp:383
std::remove_const_t< INDEX_TYPE > INDEX_TYPE_NC
Since INDEX_TYPE should always be const we need an alias for the non const version.
Definition: ArrayOfArraysView.hpp:174
LVARRAY_HOST_DEVICE void insertIntoArray(INDEX_TYPE const i, INDEX_TYPE const j, ITER const first, ITER const last) const
Insert values into an array.
Definition: ArrayOfArraysView.hpp:529
LVARRAY_HOST_DEVICE void eraseFromArray(INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const n=1) const
Erase values from an array.
Definition: ArrayOfArraysView.hpp:550
void setCapacityOfArray(INDEX_TYPE const i, INDEX_TYPE const newCapacity, BUFFERS &... buffers)
Set the capacity of the given array.
Definition: ArrayOfArraysView.hpp:877
#define ARRAYOFARRAYS_CHECK_INSERT_BOUNDS2(i, j)
Check that i is a valid array index and that j is a valid insertion index into that array...
Definition: ArrayOfArraysView.hpp:129
void assimilate(ArrayOfArraysView< T, INDEX_TYPE, CONST_SIZES, BUFFER_TYPE > &&src)
Steal the resources of src, clearing it in the process.
Definition: ArrayOfArraysView.hpp:749
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void uninitializedShiftDown(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const amount)
Shift values down into uninitialized memory.
Definition: arrayManipulation.hpp:225
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void copyInto(DST_BUFFER &dst, std::ptrdiff_t const dstSize, SRC_BUFFER const &src, std::ptrdiff_t const srcSize)
Copy values from the source buffer into the destination buffer.
Definition: bufferManipulation.hpp:393
LVARRAY_HOST_DEVICE constexpr INDEX_TYPE const * getOffsets() const
Definition: ArrayOfArraysView.hpp:352
std::conditional_t< CONST_SIZES, INDEX_TYPE const, INDEX_TYPE_NC > SIZE_TYPE
The type contained by the m_sizes buffer.
Definition: ArrayOfArraysView.hpp:177
std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U > const & > PairOfBuffers
Alias for a std::pair of buffers.
Definition: ArrayOfArraysView.hpp:604
camp::concepts::metalib::all_of_t< TYPES ... > all_of_t
A struct that contains a static constexpr bool value that is true if all of TYPES::value are true...
Definition: typeManipulation.hpp:164
LVARRAY_HOST_DEVICE constexpr INDEX_TYPE_NC size() const
Definition: ArrayOfArraysView.hpp:323
LVARRAY_HOST_DEVICE constexpr SIZE_TYPE const * getSizes() const
Definition: ArrayOfArraysView.hpp:341
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > toViewConst() const
Definition: ArrayOfArraysView.hpp:304
DISABLE_HD_WARNING constexpr LVARRAY_HOST_DEVICE std::iterator_traits< ITER >::difference_type iterDistance(ITER first, ITER const last, std::input_iterator_tag)
Definition: arrayManipulation.hpp:105
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void uninitializedShiftUp(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const amount)
Shift values up into uninitialized memory.
Definition: arrayManipulation.hpp:253
void reserveValues(INDEX_TYPE const newValueCapacity, BUFFERS &... buffers)
Reserve space for the given number of values.
Definition: ArrayOfArraysView.hpp:648
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView(ArrayOfArraysView &&src)
Default move constructor.
Definition: ArrayOfArraysView.hpp:218
#define CONSTEXPR_WITH_NDEBUG
Expands to constexpr in release builds (when NDEBUG is defined).
Definition: Macros.hpp:626
void registerTouch(MemorySpace const space) const
Touch the memory in space.
Definition: ArrayOfArraysView.hpp:570
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void emplace(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, ARGS &&... args)
Insert into the array constructing the new value in place.
Definition: arrayManipulation.hpp:478
#define LVARRAY_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Macros.hpp:485
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:549
COL_TYPE ValueType
An alias for the type contained in the inner arrays.
Definition: ArrayOfArraysView.hpp:185
void resizeFromOffsets(INDEX_TYPE const numSubArrays, INDEX_TYPE const *const offsets, BUFFERS &... buffers)
Clears the array and creates a new array with the given number of sub-arrays.
Definition: ArrayOfArraysView.hpp:698