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 
256  inline
258  {
259  m_numArrays = src.m_numArrays;
260  src.m_numArrays = 0;
261  m_offsets = std::move( src.m_offsets );
262  m_sizes = std::move( src.m_sizes );
263  m_values = std::move( src.m_values );
264  return *this;
265  }
266 
268 
272 
277  LVARRAY_HOST_DEVICE constexpr inline
279  toView() const
280  {
282  this->m_offsets,
283  this->m_sizes,
284  this->m_values );
285  }
286 
290  LVARRAY_HOST_DEVICE constexpr inline
293  {
295  this->m_offsets,
296  this->m_sizes,
297  this->m_values );
298  }
299 
303  LVARRAY_HOST_DEVICE constexpr inline
305  toViewConst() const
306  {
308  this->m_offsets,
309  this->m_sizes,
310  this->m_values );
311  }
312 
314 
318 
323  LVARRAY_HOST_DEVICE constexpr inline
325  { return m_numArrays; }
326 
332  INDEX_TYPE_NC sizeOfArray( INDEX_TYPE const i ) const
333  {
335  return m_sizes[ i ];
336  }
337 
341  LVARRAY_HOST_DEVICE constexpr inline
342  SIZE_TYPE const * getSizes() const
343  {
344  return m_sizes.data();
345  }
346 
347 
352  LVARRAY_HOST_DEVICE constexpr inline
353  INDEX_TYPE const * getOffsets() const
354  {
355  return m_offsets.data();
356  }
357 
361  LVARRAY_HOST_DEVICE constexpr inline
362  T const * getValues() const
363  {
364  return m_values.data();
365  }
366 
367 
368 
374  {
375  LVARRAY_ASSERT( m_sizes.capacity() < m_offsets.capacity());
376  return m_sizes.capacity();
377  }
378 
384  INDEX_TYPE_NC capacityOfArray( INDEX_TYPE const i ) const
385  {
387  return m_offsets[ i + 1 ] - m_offsets[ i ];
388  }
389 
393  LVARRAY_HOST_DEVICE constexpr inline
395  { return m_values.capacity(); }
396 
398 
402 
410  {
412  return ArraySlice< T, 1, 0, INDEX_TYPE_NC >( m_values.data() + m_offsets[ i ], &m_sizes[ i ], nullptr );
413  }
414 
421  T & operator()( INDEX_TYPE const i, INDEX_TYPE const j ) const
422  {
424  return m_values[m_offsets[ i ] + j];
425  }
426 
428 
432 
442  template< typename ... ARGS >
443  LVARRAY_HOST_DEVICE inline
444  void emplaceBack( INDEX_TYPE const i, ARGS && ... args ) const
445  {
448 
449  T * const ptr = m_values.data() + m_offsets[ i ];
450  arrayManipulation::emplaceBack( ptr, sizeOfArray( i ), std::forward< ARGS >( args ) ... );
451  m_sizes[ i ] += 1;
452  }
453 
463  template< typename POLICY, typename ... ARGS >
464  LVARRAY_HOST_DEVICE inline
465  void emplaceBackAtomic( INDEX_TYPE const i, ARGS && ... args ) const
466  {
468 
469  T * const ptr = m_values.data() + m_offsets[ i ];
470  INDEX_TYPE const previousSize = RAJA::atomicInc< POLICY >( &m_sizes[ i ] );
471  ARRAYOFARRAYS_ATOMIC_CAPACITY_CHECK( i, previousSize, 1 );
472 
473  arrayManipulation::emplaceBack( ptr, previousSize, std::forward< ARGS >( args ) ... );
474  }
475 
485  template< typename ITER >
486  LVARRAY_HOST_DEVICE inline
487  void appendToArray( INDEX_TYPE const i, ITER const first, ITER const last ) const
488  {
490 
491  T * const ptr = m_values.data() + m_offsets[ i ];
492  INDEX_TYPE const n = arrayManipulation::append( ptr, sizeOfArray( i ), first, last );
494  m_sizes[ i ] += n;
495  }
496 
506  template< typename ... ARGS >
507  LVARRAY_HOST_DEVICE inline
508  void emplace( INDEX_TYPE const i, INDEX_TYPE const j, ARGS && ... args ) const
509  {
512 
513  T * const ptr = m_values.data() + m_offsets[ i ];
514  arrayManipulation::emplace( ptr, sizeOfArray( i ), j, std::forward< ARGS >( args )... );
515  m_sizes[ i ]++;
516  }
517 
528  template< typename ITER >
529  LVARRAY_HOST_DEVICE inline
530  void insertIntoArray( INDEX_TYPE const i,
531  INDEX_TYPE const j,
532  ITER const first,
533  ITER const last ) const
534  {
536  INDEX_TYPE const n = arrayManipulation::iterDistance( first, last );
538 
539  T * const ptr = m_values.data() + m_offsets[ i ];
540  arrayManipulation::insert( ptr, sizeOfArray( i ), j, first, n );
541  m_sizes[ i ] += n;
542  }
543 
550  LVARRAY_HOST_DEVICE inline
551  void eraseFromArray( INDEX_TYPE const i, INDEX_TYPE const j, INDEX_TYPE const n=1 ) const
552  {
554 
555  T * const ptr = m_values.data() + m_offsets[ i ];
556  arrayManipulation::erase( ptr, sizeOfArray( i ), j, n );
557  m_sizes[ i ] -= n;
558  }
559 
561 
565 
571  void registerTouch( MemorySpace const space ) const
572  {
573  m_values.registerTouch( space );
574  m_sizes.registerTouch( space );
575  m_offsets.registerTouch( space );
576  }
577 
584  void move( MemorySpace const space, bool touch=true ) const
585  {
586  m_values.move( space, touch );
587  m_sizes.move( space, touch );
588 
589  #if defined(LVARRAY_USE_CUDA)
590  if( space == MemorySpace::cuda ) touch = false;
591  #endif
592  #if defined(LVARRAY_USE_HIP)
593  if( space == MemorySpace::hip ) touch = false;
594  #endif
595  m_offsets.move( space, touch );
596  }
597 
598 
600 
601 protected:
602 
607  template< typename U >
608  using PairOfBuffers = std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U > const & >;
609 
615  m_numArrays( 0 ),
616  m_offsets( true ),
617  m_sizes( true ),
618  m_values( true )
619  {}
620 
624 
631  void resize( INDEX_TYPE const newSize, INDEX_TYPE const defaultArrayCapacity=0 )
632  { return resizeImpl( newSize, defaultArrayCapacity ); }
633 
638  void reserve( INDEX_TYPE const newCapacity )
639  {
640  bufferManipulation::reserve( m_offsets, m_numArrays + 1, MemorySpace::host, newCapacity + 1 );
641  bufferManipulation::reserve( m_sizes, m_numArrays, MemorySpace::host, newCapacity );
642  }
643 
651  template< class ... BUFFERS >
652  void reserveValues( INDEX_TYPE const newValueCapacity, BUFFERS & ... buffers )
653  {
654  INDEX_TYPE const maxOffset = m_offsets[ m_numArrays ];
655  typeManipulation::forEachArg( [newValueCapacity, maxOffset] ( auto & buffer )
656  {
657  bufferManipulation::reserve( buffer, maxOffset, MemorySpace::host, newValueCapacity );
658  }, m_values, buffers ... );
659  }
660 
668  template< class ... BUFFERS >
669  void compress( BUFFERS & ... buffers )
670  {
671  if( m_numArrays == 0 ) return;
672 
673  for( INDEX_TYPE i = 0; i < m_numArrays - 1; ++i )
674  {
675  INDEX_TYPE const nextOffset = m_offsets[ i + 1 ];
676  INDEX_TYPE const shiftAmount = nextOffset - m_offsets[ i ] - sizeOfArray( i );
677  INDEX_TYPE const sizeOfNextArray = sizeOfArray( i + 1 );
678 
679  // Shift the values in the next array down.
681  [sizeOfNextArray, nextOffset, shiftAmount] ( auto & buffer )
682  {
683  arrayManipulation::uninitializedShiftDown( &buffer[ nextOffset ], sizeOfNextArray, shiftAmount );
684  }, m_values, buffers ... );
685 
686  // And update the offsets.
687  m_offsets[ i + 1 ] -= shiftAmount;
688  }
689 
690  // Update the last offset.
691  m_offsets[ m_numArrays ] = m_offsets[ m_numArrays - 1 ] + sizeOfArray( m_numArrays - 1 );
692  }
693 
701  template< typename ... BUFFERS >
702  void resizeFromOffsets( INDEX_TYPE const numSubArrays,
703  INDEX_TYPE const * const offsets,
704  BUFFERS & ... buffers )
705  {
706  auto const fillOffsets = [&]()
707  {
709  offsets + numSubArrays + 1,
710  m_offsets.data() );
711  };
712  resizeFromOffsetsImpl( numSubArrays, fillOffsets, buffers ... );
713  }
714 
724  template< typename POLICY, typename ... BUFFERS >
725  void resizeFromCapacities( INDEX_TYPE const numSubArrays,
726  INDEX_TYPE const * const capacities,
727  BUFFERS & ... buffers )
728  {
729  auto const fillOffsets = [&]()
730  {
731  m_offsets[ 0 ] = 0;
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:223
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, BUFFER_TYPE > toView() const
Definition: ArrayOfArraysView.hpp:279
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:409
#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:638
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
LVARRAY_HOST_DEVICE ArrayOfArraysView & operator=(ArrayOfArraysView &&src)
Move assignment operator..
Definition: ArrayOfArraysView.hpp:257
ArrayOfArraysView()=default
A constructor to create an uninitialized ArrayOfArraysView.
LVARRAY_HOST_DEVICE CONSTEXPR_WITH_NDEBUG INDEX_TYPE_NC capacity() const
Definition: ArrayOfArraysView.hpp:373
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:584
LVARRAY_HOST_DEVICE LVARRAY_FORCE_INLINE constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > min(T const a, T const b)
Definition: math.hpp:362
LVARRAY_HOST_DEVICE void emplaceBack(INDEX_TYPE const i, ARGS &&... args) const
Append a value to an array.
Definition: ArrayOfArraysView.hpp:444
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
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:487
LVARRAY_HOST_DEVICE constexpr T const * getValues() const
Definition: ArrayOfArraysView.hpp:362
#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:669
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:508
#define CONSTEXPR_WITHOUT_BOUNDS_CHECK
Expands to constexpr when array bound checking is disabled.
Definition: Macros.hpp:662
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:631
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:421
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:394
Contains functions for manipulating buffers.
LVARRAY_HOST_DEVICE CONSTEXPR_WITHOUT_BOUNDS_CHECK INDEX_TYPE_NC sizeOfArray(INDEX_TYPE const i) const
Definition: ArrayOfArraysView.hpp:332
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:292
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:465
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:725
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:614
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:384
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:530
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:551
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:353
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:608
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:324
LVARRAY_HOST_DEVICE constexpr SIZE_TYPE const * getSizes() const
Definition: ArrayOfArraysView.hpp:342
LVARRAY_HOST_DEVICE constexpr ArrayOfArraysView< T const, INDEX_TYPE const, true, BUFFER_TYPE > toViewConst() const
Definition: ArrayOfArraysView.hpp:305
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:652
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:679
void registerTouch(MemorySpace const space) const
Touch the memory in space.
Definition: ArrayOfArraysView.hpp:571
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:524
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:600
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:702