GEOSX
ArrayView.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, 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 "ArraySlice.hpp"
17 #include "Macros.hpp"
18 #include "indexing.hpp"
19 #include "limits.hpp"
20 #include "sliceHelpers.hpp"
21 #include "bufferManipulation.hpp"
22 
23 // System includes
24 #if defined(LVARRAY_USE_TOTALVIEW_OUTPUT) && !defined(__CUDA_ARCH__)
25 #include "totalview/tv_helpers.hpp"
27 #endif
28 
29 namespace LvArray
30 {
31 
62 template< typename T,
63  int NDIM_TPARAM,
64  int USD_TPARAM,
65  typename INDEX_TYPE,
66  template< typename > class BUFFER_TYPE >
67 class ArrayView
68 {
69 public:
70 
71  static_assert( NDIM_TPARAM > 0, "Number of dimensions must be greater than zero." );
72  static_assert( USD_TPARAM >= 0, "USD must be positive." );
73  static_assert( USD_TPARAM < NDIM_TPARAM, "USD must be less than NDIM." );
74 
76  using ValueType = T;
77 
79  static constexpr int NDIM = NDIM_TPARAM;
80 
82  static constexpr int USD = USD_TPARAM;
83 
85  using IndexType = INDEX_TYPE;
86 
89  NDIM, USD, INDEX_TYPE, BUFFER_TYPE >;
90 
93  NDIM, USD, INDEX_TYPE, BUFFER_TYPE >;
94 
97 
100 
102  using value_type = T;
103 
105  using size_type = INDEX_TYPE;
106 
110 
116  ArrayView() = default;
117 
125  inline LVARRAY_HOST_DEVICE constexpr
126  ArrayView( ArrayView const & source ) noexcept:
127  m_dims{ source.m_dims },
128  m_strides{ source.m_strides },
129  m_dataBuffer{ source.m_dataBuffer, source.size() },
130  m_singleParameterResizeIndex( source.m_singleParameterResizeIndex )
131  {}
132 
149  ArrayView( ArrayView && source ) = default;
150 
158  inline LVARRAY_HOST_DEVICE constexpr
161  int const singleParameterResizeIndex,
162  BUFFER_TYPE< T > const & buffer ):
163  m_dims( dims ),
164  m_strides( strides ),
165  m_dataBuffer( buffer ),
166  m_singleParameterResizeIndex( singleParameterResizeIndex )
167  {}
168 
170  ~ArrayView() = default;
171 
191  inline LVARRAY_HOST_DEVICE LVARRAY_INTEL_CONSTEXPR
193  {
194  m_dataBuffer = std::move( rhs.m_dataBuffer );
195  m_singleParameterResizeIndex = rhs.m_singleParameterResizeIndex;
196  for( int i = 0; i < NDIM; ++i )
197  {
198  m_dims[ i ] = rhs.m_dims[ i ];
199  m_strides[ i ] = rhs.m_strides[ i ];
200  }
201 
202  return *this;
203  }
204 
210  inline LVARRAY_INTEL_CONSTEXPR
211  ArrayView & operator=( ArrayView const & rhs ) noexcept
212  {
213  m_dataBuffer = rhs.m_dataBuffer;
214  m_singleParameterResizeIndex = rhs.m_singleParameterResizeIndex;
215  for( int i = 0; i < NDIM; ++i )
216  {
217  m_dims[ i ] = rhs.m_dims[ i ];
218  m_strides[ i ] = rhs.m_strides[ i ];
219  }
220 
221  return *this;
222  }
223 
225 
229 
234  inline LVARRAY_HOST_DEVICE constexpr
235  ArrayView toView() const &
237 
241  inline LVARRAY_HOST_DEVICE constexpr
243  {
245  m_strides,
247  m_dataBuffer );
248  }
249 
253  inline LVARRAY_HOST_DEVICE constexpr
255  { return reinterpret_cast< NestedViewType const & >( *this ); }
256 
260  inline LVARRAY_HOST_DEVICE constexpr
262  { return reinterpret_cast< NestedViewTypeConst const & >( *this ); }
263 
267  inline LVARRAY_HOST_DEVICE constexpr
269  toSlice() const & noexcept
271 
279  inline LVARRAY_HOST_DEVICE constexpr
281  toSlice() const && noexcept = delete;
282 
286  inline LVARRAY_HOST_DEVICE constexpr
288  toSliceConst() const & noexcept
290 
298  inline LVARRAY_HOST_DEVICE constexpr
300  toSliceConst() const && noexcept = delete;
301 
306  template< typename _T=T >
307  inline LVARRAY_HOST_DEVICE constexpr
308  operator std::enable_if_t< !std::is_const< _T >::value,
310  { return toViewConst(); }
311 
315  inline LVARRAY_HOST_DEVICE constexpr
316  operator ArraySlice< T, NDIM, USD, INDEX_TYPE >() const & noexcept
317  { return toSlice(); }
318 
326  inline LVARRAY_HOST_DEVICE constexpr
327  operator ArraySlice< T, NDIM, USD, INDEX_TYPE >() const && noexcept = delete;
328 
332  template< typename _T=T >
333  inline LVARRAY_HOST_DEVICE constexpr
334  operator std::enable_if_t< !std::is_const< _T >::value,
336  { return toSliceConst(); }
337 
345  template< typename _T=T >
346  inline LVARRAY_HOST_DEVICE constexpr
347  operator std::enable_if_t< !std::is_const< _T >::value,
348  ArraySlice< T const, NDIM, USD, INDEX_TYPE > const >() const && noexcept = delete;
349 
351 
355 
360  LVARRAY_HOST_DEVICE inline
361  INDEX_TYPE size() const noexcept
362  {
363  #if defined( __ibmxl__ )
364  // Note: This used to be done with a recursive template but XL-release would produce incorrect results.
365  // Specifically in exampleArray it would return an "old" size even after being updated, strange.
366  INDEX_TYPE val = m_dims[ 0 ];
367  for( int i = 1; i < NDIM; ++i )
368  { val *= m_dims[ i ]; }
369 
370  return val;
371  #else
372  return indexing::multiplyAll< NDIM >( m_dims.data );
373  #endif
374  }
375 
380  LVARRAY_HOST_DEVICE inline
381  INDEX_TYPE size( int const dim ) const noexcept
382  {
383 #ifdef LVARRAY_BOUNDS_CHECK
384  LVARRAY_ASSERT_GE( dim, 0 );
385  LVARRAY_ASSERT_GT( NDIM, dim );
386 #endif
387  return m_dims[dim];
388  }
389 
393  LVARRAY_HOST_DEVICE inline constexpr
394  bool empty() const
395  { return size() == 0; }
396 
400  LVARRAY_HOST_DEVICE constexpr
401  INDEX_TYPE capacity() const
402  { return LvArray::integerConversion< INDEX_TYPE >( m_dataBuffer.capacity() ); }
403 
407  LVARRAY_HOST_DEVICE inline constexpr
409  { return m_singleParameterResizeIndex; }
410 
416  template< typename ... INDICES >
418  INDEX_TYPE linearIndex( INDICES const ... indices ) const
419  {
420  static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" );
421 #ifdef LVARRAY_BOUNDS_CHECK
422  indexing::checkIndices( m_dims.data, indices ... );
423 #endif
424  return indexing::getLinearIndex< USD >( m_strides.data, indices ... );
425  }
426 
430  LVARRAY_HOST_DEVICE inline constexpr
431  INDEX_TYPE const * dims() const noexcept
432  { return m_dims.data; }
433 
437  LVARRAY_HOST_DEVICE inline constexpr
438  INDEX_TYPE const * strides() const noexcept
439  { return m_strides.data; }
440 
442 
446 
453  template< int _NDIM=NDIM >
455  std::enable_if_t< (_NDIM > 1), ArraySlice< T, NDIM - 1, USD - 1, INDEX_TYPE > >
456  operator[]( INDEX_TYPE const index ) const & noexcept
457  {
458  ARRAY_SLICE_CHECK_BOUNDS( index );
459  return ArraySlice< T, NDIM-1, USD-1, INDEX_TYPE >( data() + indexing::ConditionalMultiply< USD == 0 >::multiply( index, m_strides[ 0 ] ),
460  m_dims.data + 1,
461  m_strides.data + 1 );
462  }
463 
472  template< int _NDIM=NDIM >
474  std::enable_if_t< (_NDIM > 1), ArraySlice< T, NDIM - 1, USD - 1, INDEX_TYPE > >
475  operator[]( INDEX_TYPE const index ) const && noexcept = delete;
476 
482  template< int _NDIM=NDIM >
484  std::enable_if_t< _NDIM == 1, T & >
485  operator[]( INDEX_TYPE const index ) const & noexcept
486  {
487  ARRAY_SLICE_CHECK_BOUNDS( index );
489  }
490 
496  template< typename ... INDICES >
497  LVARRAY_HOST_DEVICE inline constexpr
498  T & operator()( INDICES... indices ) const
499  {
500  static_assert( sizeof ... (INDICES) == NDIM, "number of indices does not match NDIM" );
501  return data()[ linearIndex( indices ... ) ];
502  }
503 
507  LVARRAY_HOST_DEVICE inline constexpr
508  T * data() const
509  { return m_dataBuffer.data(); }
510 
514  LVARRAY_HOST_DEVICE inline constexpr
515  T * begin() const
516  { return data(); }
517 
521  LVARRAY_HOST_DEVICE inline constexpr
522  T * end() const
523  { return data() + size(); }
524 
528  T & front() const
529  { return data()[ 0 ]; }
530 
534  T & back() const
535  { return data()[size() - 1]; }
536 
538 
542 
550  template< typename POLICY >
551  void setValues( T const & value ) const
552  {
553  auto const view = toView();
554  RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, size() ), [value, view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i )
555  {
556  view.data()[ i ] = value;
557  } );
558  }
559 
565  template< typename POLICY >
567  {
568  for( int dim = 0; dim < NDIM; ++dim )
569  {
570  LVARRAY_ERROR_IF_NE( size( dim ), rhs.size( dim ) );
571  LVARRAY_ERROR_IF_NE_MSG( strides()[ dim ], rhs.strides()[ dim ],
572  "This method only works with Arrays with the same data layout." );
573  }
574 
575  auto const view = toView();
576  RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, size() ), [view, rhs] LVARRAY_HOST_DEVICE ( INDEX_TYPE const i )
577  {
578  view.data()[ i ] = rhs.data()[ i ];
579  } );
580  }
581 
583 
587 
593  void registerTouch( MemorySpace const space ) const
594  {
595  m_dataBuffer.registerTouch( space );
596  }
597 
598 
605  void move( MemorySpace const space, bool const touch=true ) const
606  { m_dataBuffer.moveNested( space, size(), touch ); }
607 
609 
610 #if defined(LVARRAY_USE_TOTALVIEW_OUTPUT) && !defined(__CUDA_ARCH__)
611 
616  static int TV_ttf_display_type( ArrayView const * av )
617  {
618  if( av!=nullptr )
619  {
620  int constexpr ndim = NDIM;
621  //std::cout<<"Totalview using ("<<totalview::format<T,INDEX_TYPE>(NDIM, av->m_dims )<<") for display of
622  // m_data;"<<std::endl;
623  // TV_ttf_add_row( "tv(m_data)", totalview::format< T, INDEX_TYPE >( NDIM, av->m_dims ).c_str(), (av->m_data) );
624  // TV_ttf_add_row( "m_data", totalview::format< T, INDEX_TYPE >( 0, av->m_dims ).c_str(), (av->m_data) );
625  TV_ttf_add_row( "m_dims", totalview::format< INDEX_TYPE, int >( 1, &ndim ).c_str(), (av->m_dims) );
626  TV_ttf_add_row( "m_strides", totalview::format< INDEX_TYPE, int >( 1, &ndim ).c_str(), (av->m_strides) );
627  TV_ttf_add_row( "m_dataBuffer", LvArray::demangle< BUFFER_TYPE< T > >().c_str(), &(av->m_dataBuffer) );
628  TV_ttf_add_row( "m_singleParameterResizeIndex", "int", &(av->m_singleParameterResizeIndex) );
629  }
630  return 0;
631  }
632 #endif
633 
634 protected:
635 
642  ArrayView( bool ) noexcept:
643  m_dims{ 0 },
644  m_strides{ 0 },
645  m_dataBuffer( true )
646  {
647 #if defined(LVARRAY_USE_TOTALVIEW_OUTPUT) && !defined(__CUDA_ARCH__) && defined(LVARRAY_BOUNDS_CHECK)
648  ArrayView::TV_ttf_display_type( nullptr );
649 #endif
650  }
651 
654 
657 
659  BUFFER_TYPE< T > m_dataBuffer;
660 
664 };
665 
669 template< class >
670 constexpr bool isArrayView = false;
671 
680 template< typename T,
681  int NDIM,
682  int USD,
683  typename INDEX_TYPE,
684  template< typename > class BUFFER_TYPE >
685 constexpr bool isArrayView< ArrayView< T, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > > = true;
686 
687 } // namespace LvArray
HYPRE_ParVector value_type
The type of the values in the ArrayView, here for stl compatability.
Definition: ArrayView.hpp:102
constexpr T & operator()(INDICES... indices) const
Definition: ArrayView.hpp:498
INDEX_TYPE size(int const dim) const noexcept
Definition: ArrayView.hpp:381
constexpr int getSingleParameterResizeIndex() const
Definition: ArrayView.hpp:408
constexpr ArrayView(typeManipulation::CArray< INDEX_TYPE, NDIM > const &dims, typeManipulation::CArray< INDEX_TYPE, NDIM > const &strides, int const singleParameterResizeIndex, BUFFER_TYPE< T > const &buffer)
Construct a new ArrayView from existing components.
Definition: ArrayView.hpp:159
constexpr INDEX_TYPE const * strides() const noexcept
Definition: ArrayView.hpp:438
constexpr bool isArrayView
True if the template type is a ArrayView.
Definition: ArrayView.hpp:670
This class serves to provide a sliced multidimensional interface to the family of LvArray classes...
Definition: ArraySlice.hpp:89
constexpr ArraySlice< T, NDIM, USD, INDEX_TYPE > toSlice() const &noexcept
Definition: ArrayView.hpp:269
INDEX_TYPE size() const noexcept
Definition: ArrayView.hpp:361
T & front() const
Definition: ArrayView.hpp:528
constexpr T * end() const
Definition: ArrayView.hpp:522
#define LVARRAY_ASSERT_GT(lhs, rhs)
Assert that one value compares greater than the other in debug builds.
Definition: Macros.hpp:355
Contains functions for interacting with ArraySlices of arbitrary dimension.
#define LVARRAY_ERROR_IF_NE_MSG(lhs, rhs, msg)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:230
void registerTouch(MemorySpace const space) const
Touch the memory in space.
Definition: ArrayView.hpp:593
~ArrayView()=default
The default destructor.
void checkIndices(INDEX_TYPE const *const LVARRAY_RESTRICT dims, INDICES const ... indices)
Check that the indices are with dims , if not the program is aborted.
Definition: indexing.hpp:208
constexpr ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > toViewConst() const &
Definition: ArrayView.hpp:242
Contains portable access to std::numeric_limits and functions for converting between integral types...
#define ARRAY_SLICE_CHECK_BOUNDS(index)
Point GDB at the scripts/gdb-printers.py.
Definition: ArraySlice.hpp:66
constexpr T * data() const
Definition: ArrayView.hpp:508
This class serves to provide a "view" of a multidimensional array.
Definition: ArrayView.hpp:67
#define CONSTEXPR_WITHOUT_BOUNDS_CHECK
Expands to constexpr when array bound checking is disabled.
Definition: Macros.hpp:449
typeManipulation::CArray< INDEX_TYPE, NDIM > m_dims
the dimensions of the array.
Definition: ArrayView.hpp:653
Contains the implementation of LvArray::ArraySlice.
constexpr ArrayView toView() const &
Definition: ArrayView.hpp:235
#define LVARRAY_ASSERT_GE(lhs, rhs)
Assert that one value compares greater than or equal to the other in debug builds.
Definition: Macros.hpp:370
Contains functions for manipulating buffers.
constexpr ArrayView(ArrayView const &source) noexcept
Copy Constructor.
Definition: ArrayView.hpp:126
constexpr INDEX_TYPE const * dims() const noexcept
Definition: ArrayView.hpp:431
constexpr ArraySlice< T const, NDIM, USD, INDEX_TYPE > toSliceConst() const &noexcept
Definition: ArrayView.hpp:288
static constexpr auto multiply(A const a, B const b)
Definition: indexing.hpp:47
BUFFER_TYPE< T > m_dataBuffer
this data member contains the actual data for the array.
Definition: ArrayView.hpp:659
static constexpr int USD
The unit stride dimension.
Definition: ArrayView.hpp:82
T & back() const
Definition: ArrayView.hpp:534
typeManipulation::CArray< INDEX_TYPE, NDIM > m_strides
the strides of the array.
Definition: ArrayView.hpp:656
constexpr INDEX_TYPE linearIndex(INDICES const ... indices) const
Definition: ArrayView.hpp:418
constexpr INDEX_TYPE capacity() const
Definition: ArrayView.hpp:401
void move(MemorySpace const space, bool const touch=true) const
Move the Array to the given execution space, optionally touching it.
Definition: ArrayView.hpp:605
void setValues(ArrayView< T const, NDIM, USD, INDEX_TYPE, BUFFER_TYPE > const &rhs) const
Set entries to values from another compatible ArrayView.
Definition: ArrayView.hpp:566
MemorySpace
An enum containing the available memory spaces.
The top level namespace.
Definition: Array.hpp:24
constexpr ArrayView(bool) noexcept
Protected constructor to be used by the Array class.
Definition: ArrayView.hpp:642
constexpr T * begin() const
Definition: ArrayView.hpp:515
constexpr bool empty() const
Definition: ArrayView.hpp:394
void setValues(T const &value) const
Set all entries in the array to value.
Definition: ArrayView.hpp:551
Contains a bunch of macro definitions.
constexpr NestedViewTypeConst toNestedViewConst() const &
Definition: ArrayView.hpp:261
int m_singleParameterResizeIndex
Definition: ArrayView.hpp:663
constexpr std::enable_if_t< _NDIM==1, T &> operator[](INDEX_TYPE const index) const &noexcept
Definition: ArrayView.hpp:485
constexpr NestedViewType toNestedView() const &
Definition: ArrayView.hpp:254
#define DISABLE_HD_WARNING
Disable host device warnings.
Definition: Macros.hpp:401
std::string demangle(char const *const name)
static constexpr int NDIM
The number of dimensions.
Definition: ArrayView.hpp:79
Contains functions to aid in multidimensional indexing.
#define LVARRAY_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:237
LVARRAY_INTEL_CONSTEXPR ArrayView & operator=(ArrayView &&rhs)
Move assignment operator, creates a shallow copy and invalidates the source.
Definition: ArrayView.hpp:192
ArrayView()=default
A constructor to create an uninitialized ArrayView.
LVARRAY_INTEL_CONSTEXPR ArrayView & operator=(ArrayView const &rhs) noexcept
Copy assignment operator, creates a shallow copy.
Definition: ArrayView.hpp:211
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:389