atlas
TableView.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 
21 
22 #pragma once
23 
24 #include <type_traits>
25 
26 #include "atlas/array/Table.h"
27 #include "atlas/library/config.h"
28 
29 namespace atlas {
30 namespace array {
31 
32 // --------------------------------------------------------------------------
33 
34 #if ATLAS_HAVE_FORTRAN
35 #define INDEX_REF Index
36 #define FROM_FORTRAN -1
37 #define TO_FORTRAN +1
38 #else
39 #define INDEX_REF *
40 #define FROM_FORTRAN
41 #define TO_FORTRAN
42 #endif
43 
44 namespace detail {
45 
46 // TableIndex:
47 // Helper class that does +1 and -1 operations on stored values
48 
49 class TableIndex {
50 public:
51  enum
52  {
53  BASE = 1
54  };
55 
56 public:
57  TableIndex( idx_t* idx ) : idx_( idx ) {}
58  void set( const idx_t& value ) { *( idx_ ) = value + BASE; }
59  idx_t get() const { return *(idx_)-BASE; }
60  void operator =( const idx_t& value ) { set( value ); }
61  TableIndex& operator=( const TableIndex& other ) {
62  set( other.get() );
63  return *this;
64  }
65  TableIndex& operator+( const idx_t& value ) {
66  *( idx_ ) += value;
67  return *this;
68  }
69  TableIndex& operator-( const idx_t& value ) {
70  *( idx_ ) -= value;
71  return *this;
72  }
73  TableIndex& operator--() {
74  --( *( idx_ ) );
75  return *this;
76  }
77  TableIndex& operator++() {
78  ++( *( idx_ ) );
79  return *this;
80  }
81  TableIndex& operator+=( const idx_t& value ) {
82  *( idx_ ) += value;
83  return *this;
84  }
85  TableIndex& operator-=( const idx_t& value ) {
86  *( idx_ ) -= value;
87  return *this;
88  }
89 
90  // implicit conversion
91  operator idx_t() const { return get(); }
92 
93 private:
94  idx_t* idx_;
95 };
96 
97 } // namespace detail
98 
99 // ------------------------------------------------------------------------------------------------------
100 
101 template <bool ReadOnly>
102 class TableRow {
103 #if ATLAS_HAVE_FORTRAN
104  typedef detail::TableIndex Index;
105 #else
106  typedef idx_t Index;
107 #endif
108 
109  using ReturnType = typename std::conditional<ReadOnly, idx_t, Index>::type;
110 
111 public:
112  ATLAS_HOST_DEVICE
113  TableRow( const idx_t* data, size_t size ) : data_( const_cast<idx_t*>( data ) ), size_( size ) {}
114 
115  ATLAS_HOST_DEVICE
116  idx_t operator()( size_t i ) const { return data_[i] FROM_FORTRAN; }
117 
118  ATLAS_HOST_DEVICE
119  ReturnType operator()( size_t i ) { return INDEX_REF( data_ + i ); }
120 
121  ATLAS_HOST_DEVICE
122  size_t size() const { return size_; }
123 
124  // TODO: Following function should only be allowed to compile if
125  // ReadOnly=false (SFINAE?)
126  TableRow& operator=( const idx_t column_values[] ) {
127  assert( not ReadOnly );
128  for ( size_t n = 0; n < size_; ++n ) {
129  data_[n] = column_values[n] TO_FORTRAN;
130  }
131  return *this;
132  }
133 
134 private:
135  idx_t* data_;
136  size_t size_;
137 };
138 
139 // ------------------------------------------------------------------------------------------------------
140 
141 template <bool ReadOnly>
142 class TableView : public util::Object {
143 #if ATLAS_HAVE_FORTRAN
144  using Index = typename std::conditional<ReadOnly, idx_t, detail::TableIndex>::type;
145 #else
146  using Index = idx_t;
147 #endif
148 
149 public:
150  typedef TableRow<ReadOnly> Row;
151  typedef TableRow<true> ConstRow;
152 
153  static constexpr unsigned short _values_ = 0;
154  static constexpr unsigned short _displs_ = 1;
155  static constexpr unsigned short _counts_ = 2;
156 
157 public:
158  using value_type = idx_t;
159  using Data = typename std::conditional<ReadOnly, const idx_t, idx_t>::type;
160 
161  template <typename ReturnType, bool ReadOnly_>
162  struct Access_t {};
163 
164  template <typename ReturnType>
165  struct Access_t<ReturnType, true> {
166  Access_t( const TableView<ReadOnly>* tv ) : tv_( const_cast<TableView<ReadOnly>*>( tv ) ) {}
167  TableView<ReadOnly>* tv_;
168  idx_t apply( size_t row, size_t col ) const { return tv_->values_( tv_->displs_( row ) + col ) FROM_FORTRAN; }
169  };
170 
171  template <typename ReturnType>
172  struct Access_t<ReturnType, false> {
173  Access_t( const TableView<ReadOnly>* tv ) : tv_( const_cast<TableView<ReadOnly>*>( tv ) ) {}
174  TableView<ReadOnly>* tv_;
175  Index apply( size_t row, size_t col ) const { return Index( &tv_->values_( tv_->displs_( row ) + col ) ); }
176  };
177 
180 
181  //-- Constructors
182 
183  TableView( const Table& table, bool host = true );
184 
185  TableView( const TableView& other );
186 
187  TableView operator=( const TableView& other );
188 
189  ~TableView() {}
190 
191  //-- Accessors
192 
194  ATLAS_HOST_DEVICE
195  size_t rows() const { return rows_; }
196 
198  ATLAS_HOST_DEVICE
199  size_t cols( size_t row_idx ) const { return counts_( row_idx ); }
200 
202  ATLAS_HOST_DEVICE
203  size_t maxcols() const { return maxcols_; }
204 
206  ATLAS_HOST_DEVICE
207  size_t mincols() const { return mincols_; }
208 
211  ATLAS_HOST_DEVICE
212  idx_t operator()( size_t row_idx, size_t col_idx ) const {
213  assert( counts_( row_idx ) > col_idx );
214  return const_access_.apply( row_idx, col_idx );
215  }
216 
219  ATLAS_HOST_DEVICE
220  Index operator()( size_t row_idx, size_t col_idx ) {
221  assert( counts_( row_idx ) > col_idx );
222  return access_.apply( row_idx, col_idx );
223  }
224 
228  const idx_t* data() const { return values_.data(); }
229  Data* data() { return values_.data(); }
230 
231  ATLAS_HOST_DEVICE
232  size_t size() const { return values_.size(); }
233 
234  ATLAS_HOST_DEVICE
235  idx_t missing_value() const { return missing_value_; }
236 
237  ATLAS_HOST_DEVICE
238  ConstRow row( size_t row_idx ) const { return ConstRow( values_.data() + displs_( row_idx ), counts_( row_idx ) ); }
239 
240  ATLAS_HOST_DEVICE
241  Row row( size_t row_idx ) { return Row( values_.data() + displs_( row_idx ), counts_( row_idx ) ); }
242 
244 
245  ATLAS_HOST_DEVICE
246  size_t displs( const size_t row ) const { return displs_( row ); }
247 
248 private:
249  const size_t* displs() const { return displs_.data(); }
250  const size_t* counts() const { return counts_.data(); }
251 
252 private:
253  bool host_;
254  idx_t missing_value_;
255  size_t rows_;
256  size_t maxcols_;
257  size_t mincols_;
258  ArrayView<idx_t, 1> values_;
259  ArrayView<size_t, 1> displs_;
260  ArrayView<size_t, 1> counts_;
261  ConstAccess const_access_;
262  Access access_;
263 };
264 
265 // -----------------------------------------------------------------------------------------------------
266 
267 #undef FROM_FORTRAN
268 #undef TO_FORTRAN
269 #undef INDEX_REF
270 
271 //------------------------------------------------------------------------------------------------------
272 
273 } // namespace array
274 } // namespace atlas
ATLAS_HOST_DEVICE Index operator()(size_t row_idx, size_t col_idx)
Access to connectivity table elements for given row and column The returned index has base 0 regardle...
Definition: TableView.h:220
Table.
Definition: Table.h:55
ATLAS_HOST_DEVICE size_t mincols() const
Minimum value for number of columns over all rows.
Definition: TableView.h:207
ATLAS_HOST_DEVICE size_t cols(size_t row_idx) const
Number of columns for specified row in the connectivity table.
Definition: TableView.h:199
ATLAS_HOST_DEVICE idx_t operator()(size_t row_idx, size_t col_idx) const
Access to connectivity table elements for given row and column The returned index has base 0 regardle...
Definition: TableView.h:212
Definition: TableView.h:162
ATLAS_HOST_DEVICE size_t displs(const size_t row) const
– Modifiers
Definition: TableView.h:246
Definition: Object.h:18
Definition: TableView.h:49
ATLAS_HOST_DEVICE size_t rows() const
Number of rows in the connectivity table.
Definition: TableView.h:195
const idx_t * data() const
Access to raw data.
Definition: TableView.h:228
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
Definition: TableView.h:142
ATLAS_HOST_DEVICE size_t maxcols() const
Maximum value for number of columns over all rows.
Definition: TableView.h:203
Definition: TableView.h:102