OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
multi_array_ref_openfpm.hpp
1 /*
2  * multi_array_ref_openfpm.hpp
3  *
4  * This is an heavily modified boost::multi_array version
5  *
6  * Created on: Jun 29, 2018
7  * Author: i-bird
8  */
9 
10 #ifndef MULTI_ARRAY_REF_OPENFPM_HPP_
11 #define MULTI_ARRAY_REF_OPENFPM_HPP_
12 
13 #include "util/cuda_util.hpp"
14 #include "boost/multi_array/collection_concept.hpp"
15 #include "boost/multi_array/concept_checks.hpp"
16 #include "boost/multi_array/algorithm.hpp"
17 #include <boost/mpl/placeholders.hpp>
18 #include <boost/mpl/accumulate.hpp>
19 #include <boost/mpl/multiplies.hpp>
20 #include <boost/concept_check.hpp>
21 #include "array_openfpm.hpp"
22 #include "types.hpp"
23 #include "multi_array_ref_base_openfpm.hpp"
24 #include "multi_array_ref_subarray_openfpm.hpp"
25 #include "storage_order.hpp"
26 #include "multi_array_iterator_openfpm.hpp"
27 #include "util/common.hpp"
28 
29 namespace openfpm {
30 
31 
32 
33 template <typename T, std::size_t NumDims, typename vector, typename TPtr>
35 {
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 public:
43 
44 /* typedef typename super_type::value_type value_type;*/
45  typedef typename super_type::const_reference const_reference;
47 /* typedef typename super_type::const_reverse_iterator const_reverse_iterator;*/
48  typedef T element;
49  typedef size_t size_type;
50 /* typedef typename super_type::difference_type difference_type;*/
51  typedef typename super_type::index index;
52 /* typedef typename super_type::extent_range extent_range;*/
54 
55  template <typename ExtentType>
56  explicit const_multi_array_ref_openfpm(TPtr base, const ExtentType& extents, const general_storage_order<NumDims>& so)
57  :base_(base),storage_(so)
58  {
59  init_multi_array_ref(extents);
60  }
61 
62 
63  template <class InputIterator>
64  void assign(InputIterator begin, InputIterator end)
65  {
66  boost::function_requires<boost::InputIteratorConcept<InputIterator> >();
67 
68  InputIterator in_iter = begin;
69  T* out_iter = base_;
70  std::size_t copy_count=0;
71  while (in_iter != end && copy_count < num_elements_)
72  {
73  *out_iter++ = *in_iter++;
74  copy_count++;
75  }
76  }
77 
78  size_type num_dimensions() const { return NumDims; }
79 
80  size_type size() const { return extent_sz; }
81 
82  // given reshaping functionality, this is the max possible size.
83  size_type max_size() const { return num_elements(); }
84 
85  bool empty() const { return size() == 0; }
86 
87  inline __device__ __host__ const index* strides() const {return stride_list_.data();}
88  inline __device__ __host__ const element* origin() const { return base_; }
89  inline __device__ __host__ const element* data() const { return base_; }
90 
91  size_type num_elements() const { return num_elements_; }
92 
93  const_iterator begin() const
94  {
95  return const_iterator(0,origin(),size(),strides());
96  }
97 
98  const_iterator end() const
99  {
100  return const_iterator(size(),origin(),size(),strides());
101  }
102 
104 
105  // This is used by multi_array, which is a subclass of this
106  void set_base_ptr(TPtr new_base) { base_ = new_base; }
107 
108 
109  TPtr base_;
110  storage_order_type storage_;
111  size_type extent_sz;
112  size_type num_elements_;
113  index_list stride_list_;
114 
115 private:
116 
117  // const_multi_array_ref cannot be assigned to (no deep copies!)
119 
120  void init_multi_array_ref(const index sz)
121  {
122  // calculate the extents
123  extent_sz = sz;
124 
125  this->compute_strides(stride_list_,extent_sz,storage_);
126 
127  num_elements_ = sz * size_ct::value;
128  }
129 };
130 
131 
132 template <typename T, int NumDims, typename vector>
133 class multi_array_ref_openfpm : public const_multi_array_ref_openfpm<T,NumDims,vector,T *>
134 {
136 public:
137 /* typedef typename super_type::value_type value_type;*/
138  typedef typename super_type::reference reference;
139  typedef typename super_type::iterator iterator;
140 /* typedef typename super_type::reverse_iterator reverse_iterator;*/
141  typedef typename super_type::const_reference const_reference;
142  typedef typename super_type::const_iterator const_iterator;
143 /* typedef typename super_type::const_reverse_iterator const_reverse_iterator;*/
144  typedef typename super_type::element element;
145  typedef typename super_type::size_type size_type;
146 // typedef typename super_type::difference_type difference_type;
147  typedef typename super_type::index index;
148 /* typedef typename super_type::extent_range extent_range;*/
149 
150  typedef typename super_type::storage_order_type storage_order_type;
151  typedef typename super_type::index_list index_list;
152 
154  typedef int yes_is_multi_array;
155 
156 /* typedef typename super_type::size_list size_list;*/
157 
158  template <class ExtentType>
159  explicit multi_array_ref_openfpm(T* base, const ExtentType r_sz, const general_storage_order<NumDims>& so)
160  :super_type(base,r_sz,so)
161  {
162  }
163 
164  // Assignment from other ConstMultiArray types.
165  template <typename ConstMultiArray>
166  multi_array_ref_openfpm & operator=(const ConstMultiArray& other)
167  {
168  boost::function_requires<
169  boost::multi_array_concepts::
170  ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
171 
172  // make sure the dimensions agree
173  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
174  BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
175  this->shape()));
176  // iterator-based copy
177  std::copy(other.begin(),other.end(),this->begin());
178  return *this;
179  }
180 
181  multi_array_ref_openfpm & operator=(const multi_array_ref_openfpm & other)
182  {
183  if (&other != this)
184  {
185  // make sure the dimensions agree
186 
187  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
188 
189  // iterator-based copy
190  std::copy(other.begin(),other.end(),this->begin());
191  }
192  return *this;
193  }
194 
195  multi_array_ref_openfpm & bind_ref(const multi_array_ref_openfpm & other)
196  {
197  if (&other != this) {
198 
199  this->base_ = other.base_;
200  this->storage_ = other.storage_;
201  this->extent_sz = other.extent_sz;
202  this->stride_list_ = other.stride_list_;
203  this->num_elements_ = other.num_elements_;
204  }
205  return *this;
206  }
207 
208  /* \brief Set the internal pointer
209  *
210  * \param base internal pointer
211  *
212  */
213  void set_pointer(void * base)
214  {
215  this->base_ = static_cast<T *>(base);
216  }
217 
218  /* \brief Get the internal pointer
219  *
220  * \return the internal pointer
221  *
222  */
223  __device__ __host__ void * get_pointer()
224  {
225  return this->base_;
226  }
227 
228  /* \brief Get the internal pointer
229  *
230  * \return the internal pointer
231  *
232  */
233  __device__ __host__ const void * get_pointer() const
234  {
235  return this->base_;
236  }
237 
238  multi_array_ref_openfpm & operator=(multi_array_ref_openfpm && other)
239  {
240  swap(other);
241 
242  return *this;
243  }
244 
245  void swap(multi_array_ref_openfpm & other)
246  {
247  T* base_tmp = this->base_;
248  this->base_ = other.base_;
249  other.base_ = base_tmp;
250 
251  storage_order_type storage_tmp = this->storage_;
252  this->storage_ = other.storage_;
253  other.storage_ = storage_tmp;
254 
255  size_type extent_tmp = this->extent_sz;
256  this->extent_sz = other.extent_sz;
257  other.extent_sz = extent_tmp;
258 
259  index_list stride_list_tmp = this->stride_list_;
260  this->stride_list_ = other.stride_list_;
261  other.stride_list_ = stride_list_tmp;
262 
263  size_type num_elements_tmp = this->num_elements_;
264  this->num_elements_ = other.num_elements_;
265  other.num_elements_ = num_elements_tmp;
266  }
267 
268  __device__ __host__ element* origin() { return super_type::base_; }
269 
270  __device__ __host__ const element* origin() const { return super_type::origin(); }
271 
272  __device__ __host__ reference operator[](index idx)
273  {
274  return super_type::access(boost::type<reference>(),
275  idx,
276  this->strides(),
277  this->origin());
278  }
279 
280 
281 
282  iterator begin()
283  {return iterator(0,origin(),this->size(),this->strides());}
284 
285  iterator end()
286  {return iterator(this->size(),origin(),this->size(),this->strides());}
287 
288  __inline__ __device__ __host__ const_reference operator[](index idx) const
289  {
290  return super_type::access(boost::type<const_reference>(),
291  idx,
292  this->strides(),
293  this->origin());
294  }
295 
296  const_iterator begin() const
297  {return super_type::begin();}
298 
299  const_iterator end() const
300  {return super_type::end();}
301 };
302 
303 template<typename T, typename Sfinae = void>
304 struct is_multi_array: std::false_type {};
305 
306 
318 template<typename T>
319 struct is_multi_array<T, typename Void<typename T::yes_is_multi_array >::type> : std::true_type
320 {};
321 
322 } // namespace openfpm
323 
324 
325 #endif /* MULTI_ARRAY_REF_OPENFPM_HPP_ */
convert a type into constant type
Definition: aggregate.hpp:292
Void structure.
Definition: common.hpp:73
int yes_is_multi_array
indicate that this class is a multi dimensional array
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202