atlas
GridToolsArrayView.h
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
11 #pragma once
12 
13 #include <cassert>
14 #include <cstddef>
15 #include <cstring>
16 #include <type_traits>
17 
18 #include "atlas/array/Array.h"
19 #include "atlas/array/ArrayUtil.h"
20 #include "atlas/array/ArrayViewDefs.h"
21 #include "atlas/array/LocalView.h"
22 #include "atlas/array/gridtools/GridToolsMakeView.h"
23 #include "atlas/array/gridtools/GridToolsTraits.h"
24 #include "atlas/library/config.h"
25 
26 //------------------------------------------------------------------------------------------------------
27 
28 namespace atlas {
29 namespace array {
30 
31 template <typename Value, int Rank>
32 class ArrayView {
33  template <typename T>
34  using is_non_const_value_type = typename std::is_same<T, typename std::remove_const<Value>::type>;
35 
36 #define ENABLE_IF_NON_CONST \
37  template <bool EnableBool = true, \
38  typename std::enable_if<( !std::is_const<Value>::value && EnableBool ), int>::type* = nullptr>
39 
40 #define ENABLE_IF_CONST_WITH_NON_CONST( T ) \
41  template <typename T, \
42  typename std::enable_if<( std::is_const<Value>::value && is_non_const_value_type<T>::value ), \
43  int>::type* = nullptr>
44 
45 public:
46  // -- Type definitions
47  using value_type = Value;
48  using non_const_value_type = typename std::remove_const<Value>::type;
49  static constexpr bool is_const = std::is_const<Value>::value;
50  static constexpr bool is_non_const = !std::is_const<Value>::value;
51 
52  // static constexpr Intent ACCESS{AccessMode};
53  static constexpr int RANK{Rank};
54 
55 
56  using data_view_t = gridtools::data_view_tt<Value, Rank, gridtools::get_access_mode<Value>()>;
57 
58 private:
59  using slicer_t = typename helpers::ArraySlicer<ArrayView<Value, Rank>>;
60  using const_slicer_t = typename helpers::ArraySlicer<const ArrayView<const Value, Rank>>;
61 
62  template <typename... Args>
63  struct slice_t {
64  using type = typename slicer_t::template Slice<Args...>::type;
65  };
66 
67  template <typename... Args>
68  struct const_slice_t {
69  using type = typename const_slicer_t::template Slice<Args...>::type;
70  };
71 
72 public:
73  ATLAS_HOST_DEVICE
74  ArrayView( const ArrayView& other );
75  ArrayView( const Array& array, bool device_view );
76 
77  ENABLE_IF_CONST_WITH_NON_CONST( value_type )
78  ArrayView( const ArrayView<value_type, Rank>& other ) :
79  gt_data_view_( other.is_device_view_ ? gridtools::make_gt_device_view<Value, Rank>( *other.array_ )
80  : gridtools::make_gt_host_view<Value, Rank>( *other.array_ ) ),
81  data_store_orig_( other.data_store_orig_ ),
82  array_( other.array_ ),
83  is_device_view_( other.is_device_view_ ) {
84  std::memcpy( shape_, other.shape_, sizeof( ArrayShape::value_type ) * Rank );
85  std::memcpy( strides_, other.strides_, sizeof( ArrayStrides::value_type ) * Rank );
86  size_ = other.size_;
87  // TODO: check compatibility
88  }
89 
90  ENABLE_IF_CONST_WITH_NON_CONST( value_type )
91  operator const ArrayView<value_type, Rank>&() const { return *(const ArrayView<value_type, Rank>*)( this ); }
92 
93  value_type* data() { return gt_data_view_.data(); }
94  value_type const* data() const { return gt_data_view_.data(); }
95 
96  template <typename... Coords, typename = typename std::enable_if<( sizeof...( Coords ) == Rank ), int>::type>
97  ATLAS_HOST_DEVICE value_type& operator()( Coords... c ) {
98  assert( sizeof...( Coords ) == Rank );
99  return gt_data_view_( c... );
100  }
101 
102  template <typename... Coords, typename = typename std::enable_if<( sizeof...( Coords ) == Rank ), int>::type>
103  ATLAS_HOST_DEVICE value_type const& operator()( Coords... c ) const {
104  assert( sizeof...( Coords ) == Rank );
105  return gt_data_view_( c... );
106  }
107 
108  template <typename Int, bool EnableBool = true>
109  ATLAS_HOST_DEVICE typename std::enable_if<( Rank == 1 && EnableBool ), const value_type&>::type operator[](
110  Int idx ) const {
111  return gt_data_view_( idx );
112  }
113 
114  template <typename Int, bool EnableBool = true>
115  ATLAS_HOST_DEVICE typename std::enable_if<( Rank == 1 && EnableBool ), value_type&>::type operator[]( Int idx ) {
116  return gt_data_view_( idx );
117  }
118 
119  template <unsigned int Dim>
120  ATLAS_HOST_DEVICE idx_t shape() const {
121  return gt_data_view_.template length<Dim>();
122  }
123 
124  ATLAS_HOST_DEVICE
125  data_view_t& data_view() { return gt_data_view_; }
126  ATLAS_HOST_DEVICE
127  data_view_t const& data_view() const { return gt_data_view_; }
128 
129  template <unsigned int Dim>
130  ATLAS_HOST_DEVICE idx_t stride() const {
131  return gt_data_view_.storage_info().template stride<Dim>();
132  }
133 
134  static constexpr idx_t rank() { return Rank; }
135  size_t size() const { return size_; }
136  bool valid() const;
137 
138  bool contiguous() const { return ( size_ == size_t( shape_[0] ) * size_t( strides_[0] ) ? true : false ); }
139 
140  void dump( std::ostream& os ) const;
141 
142  ENABLE_IF_NON_CONST
143  void assign( const value_type& value );
144 
145  ENABLE_IF_NON_CONST
146  void assign( const std::initializer_list<value_type>& list );
147 
148  const idx_t* strides() const { return strides_; }
149 
150  const idx_t* shape() const { return shape_; }
151 
152  template <typename Int>
153  idx_t shape( Int idx ) const {
154  return shape_[idx];
155  }
156 
157  template <typename Int>
158  idx_t stride( Int idx ) const {
159  return strides_[idx];
160  }
161 
162  template <typename... Args>
163  typename slice_t<Args...>::type slice( Args... args ) {
164  return slicer_t( *this ).apply( args... );
165  }
166 
167  template <typename... Args>
168  typename const_slice_t<Args...>::type slice( Args... args ) const {
169  return const_slicer_t( *this ).apply( args... );
170  }
171 
172  bool isDeviceView() const { return is_device_view_; }
173 
174  // Befriend all template variations
175  template <typename friendValue, int friendRank>
176  friend class ArrayView;
177 
178 private:
179  data_view_t gt_data_view_;
180  idx_t shape_[Rank];
181  idx_t strides_[Rank];
182  size_t size_;
183  ArrayDataStore const* data_store_orig_;
184  Array const* array_;
185  bool is_device_view_{false};
186 #undef ENABLE_IF_NON_CONST
187 #undef ENABLE_IF_CONST_WITH_NON_CONST
188 };
189 
190 //------------------------------------------------------------------------------------------------------
191 
192 } // namespace array
193 } // namespace atlas
Definition: ArraySlicer.h:110
Multi-dimensional access to a Array object or Field object.
Definition: GridToolsArrayView.h:32
Definition: test_array_slicer.cc:22
Definition: ArrayUtil.h:46
Definition: Array.h:37
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42
This file contains the LocalView class, a class that allows to wrap any contiguous raw data into a vi...