OpenFPM  5.2.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, typename StorageOrder>
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;*/
53 
54  template <typename ExtentType>
55  explicit const_multi_array_ref_openfpm(TPtr base, const ExtentType& extents)
56  :base_(base)
57  {
58  init_multi_array_ref(extents);
59  }
60 
61 
62  template <class InputIterator>
63  void assign(InputIterator begin, InputIterator end)
64  {
65  boost::function_requires<boost::InputIteratorConcept<InputIterator> >();
66 
67  InputIterator in_iter = begin;
68  T* out_iter = base_;
69  std::size_t copy_count=0;
70  while (in_iter != end && copy_count < num_elements_)
71  {
72  *out_iter++ = *in_iter++;
73  copy_count++;
74  }
75  }
76 
77  size_type num_dimensions() const { return NumDims; }
78 
79  size_type size() const { return extent_sz; }
80 
81  // given reshaping functionality, this is the max possible size.
82  size_type max_size() const { return num_elements(); }
83 
84  bool empty() const { return size() == 0; }
85 
86  inline __device__ __host__ const index* strides() const {return stride_list_.data();}
87  inline __device__ __host__ const element* origin() const { return base_; }
88  inline __device__ __host__ const element* data() const { return base_; }
89 
90  size_type num_elements() const { return num_elements_; }
91 
92  const_iterator begin() const
93  {
94  return const_iterator(0,origin(),size(),strides());
95  }
96 
97  const_iterator end() const
98  {
99  return const_iterator(size(),origin(),size(),strides());
100  }
101 
103 
104  // This is used by multi_array, which is a subclass of this
105  void set_base_ptr(TPtr new_base) { base_ = new_base; }
106 
107 
108  TPtr base_;
109  size_type extent_sz;
110  size_type num_elements_;
111  index_list stride_list_;
112 
113 private:
114 
115  // const_multi_array_ref cannot be assigned to (no deep copies!)
117 
118  void init_multi_array_ref(const index sz)
119  {
120  // calculate the extents
121  extent_sz = sz;
122 
123  this->template compute_strides<StorageOrder>(stride_list_,extent_sz);
124 
125  num_elements_ = sz * size_ct::value;
126  }
127 };
128 
129 
130 template <typename T, int NumDims, typename vector, typename StorageOrder>
132 {
134 public:
135 /* typedef typename super_type::value_type value_type;*/
136  typedef typename super_type::reference reference;
137  typedef typename super_type::iterator iterator;
138 /* typedef typename super_type::reverse_iterator reverse_iterator;*/
139  typedef typename super_type::const_reference const_reference;
141 /* typedef typename super_type::const_reverse_iterator const_reverse_iterator;*/
142  typedef typename super_type::element element;
143  typedef typename super_type::size_type size_type;
144 // typedef typename super_type::difference_type difference_type;
145  typedef typename super_type::index index;
146 /* typedef typename super_type::extent_range extent_range;*/
147 
148  typedef typename super_type::index_list index_list;
149 
151  typedef int yes_is_multi_array;
152 
153 /* typedef typename super_type::size_list size_list;*/
154 
155  template <class ExtentType>
156  explicit multi_array_ref_openfpm(T* base, const ExtentType r_sz)
157  :super_type(base,r_sz)
158  {
159  }
160 
161  // Assignment from other ConstMultiArray types.
162  template <typename ConstMultiArray>
163  multi_array_ref_openfpm & operator=(const ConstMultiArray& other)
164  {
165  boost::function_requires<
166  boost::multi_array_concepts::
167  ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
168 
169  // make sure the dimensions agree
170  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
171  BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
172  this->shape()));
173  // iterator-based copy
174  std::copy(other.begin(),other.end(),this->begin());
175  return *this;
176  }
177 
178  multi_array_ref_openfpm & operator=(const multi_array_ref_openfpm & other)
179  {
180  if (&other != this)
181  {
182  // make sure the dimensions agree
183 
184  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
185 
186  // iterator-based copy
187  std::copy(other.begin(),other.end(),this->begin());
188  }
189  return *this;
190  }
191 
192  multi_array_ref_openfpm & bind_ref(const multi_array_ref_openfpm & other)
193  {
194  if (&other != this) {
195 
196  this->base_ = other.base_;
197  this->extent_sz = other.extent_sz;
198  this->stride_list_ = other.stride_list_;
199  this->num_elements_ = other.num_elements_;
200  }
201  return *this;
202  }
203 
204  /* \brief Set the internal pointer
205  *
206  * \param base internal pointer
207  *
208  */
209  void set_pointer(void * base)
210  {
211  this->base_ = static_cast<T *>(base);
212  }
213 
214  /* \brief Get the internal pointer
215  *
216  * \return the internal pointer
217  *
218  */
219  __device__ __host__ void * get_pointer()
220  {
221  return this->base_;
222  }
223 
224  /* \brief Get the internal pointer
225  *
226  * \return the internal pointer
227  *
228  */
229  __device__ __host__ const void * get_pointer() const
230  {
231  return this->base_;
232  }
233 
234  multi_array_ref_openfpm & operator=(multi_array_ref_openfpm && other)
235  {
236  swap(other);
237 
238  return *this;
239  }
240 
241  void swap(multi_array_ref_openfpm & other)
242  {
243  T* base_tmp = this->base_;
244  this->base_ = other.base_;
245  other.base_ = base_tmp;
246 
247  size_type extent_tmp = this->extent_sz;
248  this->extent_sz = other.extent_sz;
249  other.extent_sz = extent_tmp;
250 
251  index_list stride_list_tmp = this->stride_list_;
252  this->stride_list_ = other.stride_list_;
253  other.stride_list_ = stride_list_tmp;
254 
255  size_type num_elements_tmp = this->num_elements_;
256  this->num_elements_ = other.num_elements_;
257  other.num_elements_ = num_elements_tmp;
258  }
259 
260  __device__ __host__ element* origin() { return super_type::base_; }
261 
262  __device__ __host__ const element* origin() const { return super_type::origin(); }
263 
264  __device__ __host__ reference operator[](index idx)
265  {
266  return super_type::access(boost::type<reference>(),
267  idx,
268  this->strides(),
269  this->origin());
270  }
271 
272 
273 
274  iterator begin()
275  {return iterator(0,origin(),this->size(),this->strides());}
276 
277  iterator end()
278  {return iterator(this->size(),origin(),this->size(),this->strides());}
279 
280  __inline__ __device__ __host__ const_reference operator[](index idx) const
281  {
282  return super_type::access(boost::type<const_reference>(),
283  idx,
284  this->strides(),
285  this->origin());
286  }
287 
288  const_iterator begin() const
289  {return super_type::begin();}
290 
291  const_iterator end() const
292  {return super_type::end();}
293 };
294 
295 template<typename T, typename Sfinae = void>
296 struct is_multi_array: std::false_type {};
297 
298 
310 template<typename T>
311 struct is_multi_array<T, typename Void<typename T::yes_is_multi_array >::type> : std::true_type
312 {};
313 
314 } // namespace openfpm
315 
316 
317 #endif /* MULTI_ARRAY_REF_OPENFPM_HPP_ */
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:204
convert a type into constant type
Definition: aggregate.hpp:302
Void structure.
Definition: common.hpp:74