OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
multi_array_view_openfpm.hpp
1 /*
2  * multi_array_view_openfpm.hpp
3  *
4  * Created on: Jul 1, 2018
5  * Author: i-bird
6  */
7 
8 #ifndef MULTI_ARRAY_VIEW_OPENFPM_HPP_
9 #define MULTI_ARRAY_VIEW_OPENFPM_HPP_
10 
11 //#include "util/boost/boost_multi_array_base_openfpm.hpp"
12 #include "boost/utility/enable_if.hpp"
13 #include "boost/multi_array/index_gen.hpp"
14 
15 namespace openfpm {
16 namespace detail {
17 namespace multi_array {
18 
19 
20 
21 // TPtr = const T* defaulted in base.hpp
22 template <typename T, std::size_t NumDims, typename vector>
23 class const_multi_array_view_openfpm : public openfpm::detail::multi_array::multi_array_impl_base_openfpm<T,NumDims,vector>
24 {
26 public:
27  typedef typename super_type::value_type value_type;
28  typedef typename super_type::const_reference const_reference;
29  typedef typename super_type::const_iterator const_iterator;
30  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
31  typedef typename super_type::element element;
32  typedef typename super_type::size_type size_type;
33  typedef typename super_type::difference_type difference_type;
34  typedef typename super_type::index index;
35  typedef typename super_type::extent_range extent_range;
36  typedef T * TPtr;
37 
38  typedef typename boost::mpl::accumulate<vector,
39  typename boost::mpl::int_<1>,
40  typename boost::mpl::multiplies<typename boost::mpl::_2,typename boost::mpl::_1> >::type size_ct;
41 
42  // template typedefs
43  template <std::size_t NDims>
46  };
47 
48  template <std::size_t NDims>
51  };
52 
53  template <typename OPtr>
56  base_(other.base_), origin_offset_(other.origin_offset_),
57  num_elements_(other.num_elements_),
58  stride_list_(other.stride_list_), index_base_list_(other.index_base_list_)
59  { }
60 
61 
62  template <class BaseList>
63 #ifdef BOOST_NO_SFINAE
64  void
65 #else
66  typename
67  boost::disable_if<typename boost::is_integral<BaseList>::type,void >::type
68 #endif
69  reindex(const BaseList& values)
70  {
71  boost::function_requires<
72  boost::CollectionConcept<BaseList> >();
73  boost::detail::multi_array::
74  copy_n(values.begin(),num_dimensions(),index_base_list_.begin());
75  origin_offset_ =
76  this->calculate_indexing_offset(stride_list_,index_base_list_);
77  }
78 
79  void reindex(index value)
80  {
81  index_base_list_.assign(value);
82  origin_offset_ =
83  this->calculate_indexing_offset(stride_list_,index_base_list_);
84  }
85 
86  size_type num_dimensions() const { return NumDims; }
87 
88  size_type size() const { return extent; }
89  size_type max_size() const { return num_elements(); }
90  bool empty() const { return size() == 0; }
91 
92  __device__ __host__ const index* strides() const {
93  return stride_list_.data();
94  }
95 
96  __device__ __host__ const T* origin() const { return base_+origin_offset_; }
97 
98  size_type num_elements() const { return num_elements_; }
99 
100  __device__ __host__ const index* index_bases() const {
101  return index_base_list_.data();
102  }
103 
104  template <typename IndexList>
105  const element& operator()(IndexList indices) const
106  {
107  boost::function_requires<boost::CollectionConcept<IndexList> >();
108  return super_type::access_element(boost::type<const element&>(),
109  indices,origin(),strides(),index_bases());
110  }
111 
112  // Only allow const element access
113  __device__ __host__ const_reference operator[](index idx) const {
114  return super_type::access(boost::type<const_reference>(),
115  idx,origin(),strides(),
116  index_bases());
117  }
118 
119  // see generate_array_view in base.hpp
120  template <int NDims>
121  __device__ __host__ typename const_array_view_openfpm<NDims>::type
122  operator[](const boost::detail::multi_array::index_gen<NumDims,NDims>& indices) const
123  {
124  typedef typename const_array_view_openfpm<NDims>::type return_type;
125  return
126  super_type::generate_array_view(boost::type<return_type>(),
127  indices,
128  strides(),
129  index_bases(),
130  origin());
131  }
132 
133  const_iterator begin() const {
134  return const_iterator(*index_bases(),origin(),strides(),index_bases());
135  }
136 
137  const_reverse_iterator rend() const {
138  return const_reverse_iterator(begin());
139  }
140 
141  template <typename OPtr>
142  bool operator!=(const const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs) const
143  {
144  return !(*this == rhs);
145  }
146 
147  template <typename OPtr>
148  bool operator>(const
149  const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs)
150  const {
151  return rhs < *this;
152  }
153 
154  template <typename OPtr>
155  bool operator<=(const
156  const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs)
157  const {
158  return !(*this > rhs);
159  }
160 
161  template <typename OPtr>
162  bool operator>=(const
163  const_multi_array_view_openfpm<T,NumDims,OPtr>& rhs)
164  const {
165  return !(*this < rhs);
166  }
167 
168 
169 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
170 protected:
171  template <typename,std::size_t,typename> friend class multi_array_impl_base_openfpm;
172  template <typename,std::size_t,typename> friend class const_multi_array_view_openfpm;
173 #else
174 public: // should be protected
175 #endif
176 
177  // This constructor is used by multi_array_impl_base::generate_array_view
178  // to create strides
179  template <typename ExtentType, typename Index>
180  explicit const_multi_array_view_openfpm(TPtr base,
181  const ExtentType extent,
182  const boost::array<Index,NumDims>& strides):
183  base_(base), origin_offset_(0) ,extent(extent)
184  {
185 
186  index_base_list_.assign(0);
187 
188  // Get the extents and strides
189  boost::detail::multi_array::
190  copy_n(strides.begin(),NumDims,stride_list_.begin());
191 
192  // Calculate the array size
193  num_elements_ = extent * size_ct::type::value;
194  }
195 
196  typedef boost::array<index,NumDims> index_list;
197 
198  TPtr base_;
199  index origin_offset_;
200  size_type num_elements_;
201  size_type extent;
202  index_list stride_list_;
203  index_list index_base_list_;
204 
205 private:
206  // const_multi_array_view cannot be assigned to (no deep copies!)
207  const_multi_array_view_openfpm& operator=(const const_multi_array_view_openfpm& other);
208 };
209 
210 
211 template <typename T, std::size_t NumDims>
212 class multi_array_view_openfpm :
213  public const_multi_array_view_openfpm<T,NumDims,T*>
214 {
215  typedef const_multi_array_view_openfpm<T,NumDims,T*> super_type;
216 public:
217  typedef typename super_type::value_type value_type;
218  typedef typename super_type::reference reference;
219  typedef typename super_type::iterator iterator;
220  typedef typename super_type::reverse_iterator reverse_iterator;
221  typedef typename super_type::const_reference const_reference;
222  typedef typename super_type::const_iterator const_iterator;
223  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
224  typedef typename super_type::element element;
225  typedef typename super_type::size_type size_type;
226  typedef typename super_type::difference_type difference_type;
227  typedef typename super_type::index index;
228  typedef typename super_type::extent_range extent_range;
229 
230  // template typedefs
231  template <std::size_t NDims>
233  {
235  };
236 
237  template <std::size_t NDims>
240  };
241 
242  // Assignment from other ConstMultiArray types.
243  template <typename ConstMultiArray>
244  multi_array_view_openfpm& operator=(const ConstMultiArray& other) {
245  boost::function_requires<
246  boost::multi_array_concepts::
247  ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
248 
249  // make sure the dimensions agree
250  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
251  BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
252  this->shape()));
253  // iterator-based copy
254  std::copy(other.begin(),other.end(),begin());
255  return *this;
256  }
257 
258 
259  multi_array_view_openfpm& operator=(const multi_array_view_openfpm& other) {
260  if (&other != this) {
261  // make sure the dimensions agree
262  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
263  BOOST_ASSERT(std::equal(other.shape(),
264  other.shape()+this->num_dimensions(),
265  this->shape()));
266  // iterator-based copy
267  std::copy(other.begin(),other.end(),begin());
268  }
269  return *this;
270  }
271 
272  element* origin() { return this->base_+this->origin_offset_; }
273 
274  template <class IndexList>
275  element& operator()(const IndexList& indices) {
276  boost::function_requires<
277  boost::CollectionConcept<IndexList> >();
278  return super_type::access_element(boost::type<element&>(),
279  indices,origin(),
280  this->shape(),this->strides(),
281  this->index_bases());
282  }
283 
284 
285  reference operator[](index idx) {
286  return super_type::access(boost::type<reference>(),
287  idx,origin(),
288  this->shape(),this->strides(),
289  this->index_bases());
290  }
291 
292 
293  // see generate_array_view in base.hpp
294 /* template <int NDims>
295  typename array_view_openfpm<NDims>::type
296  operator[](const boost::detail::multi_array::
297  index_gen<NumDims,NDims>& indices) {
298  typedef typename array_view_openfpm<NDims>::type return_type;
299  return
300  super_type::generate_array_view(boost::type<return_type>(),
301  indices,
302  this->shape(),
303  this->strides(),
304  this->index_bases(),
305  origin());
306  }*/
307 
308 
309  iterator begin() {
310  return iterator(*this->index_bases(),origin(),
311  this->shape(),this->strides(),
312  this->index_bases());
313  }
314 
315  iterator end() {
316  return iterator(*this->index_bases()+(index)*this->shape(),origin(),
317  this->shape(),this->strides(),
318  this->index_bases());
319  }
320 
321  reverse_iterator rbegin() {
322  return reverse_iterator(end());
323  }
324 
325  reverse_iterator rend() {
326  return reverse_iterator(begin());
327  }
328 
329  // Using declarations don't seem to work for g++
330  // These are the proxies to work around this.
331 
332  const element* origin() const { return super_type::origin(); }
333 
334  template <class IndexList>
335  const element& operator()(const IndexList& indices) const {
336  boost::function_requires<
337  boost::CollectionConcept<IndexList> >();
338  return super_type::operator()(indices);
339  }
340 
341  const_reference operator[](index idx) const {
342  return super_type::operator[](idx);
343  }
344 
345  // see generate_array_view in base.hpp
346 /* template <int NDims>
347  typename const_array_view_openfpm<NDims>::type
348  operator[](const boost::detail::multi_array::
349  index_gen<NumDims,NDims>& indices)
350  const {
351  return super_type::operator[](indices);
352  }*/
353 
354  const_iterator begin() const {
355  return super_type::begin();
356  }
357 
358  const_iterator end() const {
359  return super_type::end();
360  }
361 
362  const_reverse_iterator rbegin() const {
363  return super_type::rbegin();
364  }
365 
366  const_reverse_iterator rend() const {
367  return super_type::rend();
368  }
369 
370 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
371 private:
372  template <typename,std::size_t> friend class multi_array_impl_base;
373 #else
374 public: // should be private
375 #endif
376 
377  // constructor used by multi_array_impl_base::generate_array_view to
378  // generate array views
379  template <typename ExtentList, typename Index>
380  explicit multi_array_view_openfpm(T* base,
381  const ExtentList& extents,
382  const openfpm::array<Index,NumDims>& strides) :
383  super_type(base,extents,strides) { }
384 
385 };
386 
387 } // namespace multi_array
388 } // namespace detail
389 
390 //
391 // traits classes to get array_view types
392 //
393 template <typename Array, int N>
395  typedef typename Array::element element;
396 public:
398 };
399 
400 template <typename Array, int N>
402  typedef typename Array::element element;
403 public:
405 };
406 
407 } // namespace boost
408 
409 
410 
411 #endif /* MULTI_ARRAY_VIEW_OPENFPM_HPP_ */
convert a type into constant type
Definition: aggregate.hpp:292
This class is a trick to indicate the compiler a specific specialization pattern.
Definition: memory_c.hpp:239