OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
multi_array_ref_base_openfpm.hpp
1 /*
2  * multi_array_ref_openfpm_base.hpp
3  *
4  * Created on: Jun 30, 2018
5  * Author: i-bird
6  */
7 
8 #ifndef MULTI_ARRAY_REF_OPENFPM_BASE_HPP_
9 #define MULTI_ARRAY_REF_OPENFPM_BASE_HPP_
10 
11 #include "types.hpp"
12 #include <boost/mpl/size_t.hpp>
13 #include "boost/iterator/reverse_iterator.hpp"
14 #include "storage_order.hpp"
15 #include <boost/mpl/at.hpp>
16 #include <boost/mpl/size.hpp>
17 #include <boost/mpl/pop_front.hpp>
18 #include <boost/type.hpp>
19 
20 namespace openfpm
21 {
22 
24 // class declarations
26 
27 //template<typename T, std::size_t NumDims, typename Allocator = std::allocator<T> >
28 //class multi_array_openfpm;
29 
30 template <typename T, int NumDims, typename vector>
32 
33 // This is a public interface for use by end users!
34 namespace multi_array_types
35 {
36  typedef openfpm::detail::multi_array::size_type size_type;
37  typedef std::ptrdiff_t difference_type;
38  typedef openfpm::detail::multi_array::index index;
39 }
40 
41 
42 namespace detail {
43 namespace multi_array {
44 
45 template <typename T, std::size_t NumDims, typename vector>
47 
48 template <typename T, std::size_t NumDims, typename vector, typename TPtr = const T*>
50 
51  template <typename T, typename TPtr, typename NumDims, typename vector, typename Reference,
52  typename IteratorCategory>
54 
55 template <typename T, std::size_t NumDims, typename TPtr = const T*>
57 
58 template <typename T, std::size_t NumDims>
60 
61 
63 // class interfaces
65 
67 {
68 public:
69  typedef multi_array_types::size_type size_type;
70  typedef multi_array_types::difference_type difference_type;
71  typedef multi_array_types::index index;
72 };
73 
74 //
75 // value_accessor_n
76 // contains the routines for accessing elements from
77 // N-dimensional views.
78 //
79 template<typename T, std::size_t NumDims, typename vector>
81 {
83 public:
84  typedef typename super_type::index index;
85 
86  //
87  // public typedefs used by classes that inherit from this base
88  //
89  typedef T element;
90  typedef openfpm::multi_array_ref_openfpm<T,NumDims-1,typename boost::mpl::pop_front<vector>::type> value_type;
91  typedef sub_array_openfpm<T,NumDims-1,typename boost::mpl::pop_front<vector>::type> reference;
92  typedef const_sub_array_openfpm<T,NumDims-1,typename boost::mpl::pop_front<vector>::type> const_reference;
93 
94 protected:
95 
96  // used by array operator[] and iterators to get reference types.
97  template <typename Reference, typename TPtr>
98  __device__ __host__ inline Reference access(boost::type<Reference>,
99  index idx,
100  const index* strides,
101  TPtr base) const
102  {
103  TPtr newbase = base + idx * strides[0];
104  return Reference(newbase,strides+1);
105  }
106 
107  __device__ __host__ value_accessor_n_openfpm() { }
108  __device__ __host__ ~value_accessor_n_openfpm() { }
109 };
110 
111 template <class T> inline __device__ __host__ void ignore_unused_variable_warning_ofp(T const&) {}
112 
113 //
114 // value_accessor_one
115 // contains the routines for accessing reference elements from
116 // 1-dimensional views.
117 //
118 template<typename T, typename vector>
120 {
122 public:
123  typedef typename super_type::index index;
124  //
125  // public typedefs for use by classes that inherit it.
126  //
127  typedef T element;
128  typedef T value_type;
129  typedef T& reference;
130  typedef T const& const_reference;
131 
132 protected:
133 
134  // used by array operator[] and iterators to get reference types.
135  template <typename Reference, typename TPtr>
136  inline __device__ __host__ Reference access(boost::type<Reference>,index idx,
137  const index* strides,
138  TPtr base) const
139  {
140  return *(base + idx * strides[0]);
141  }
142 
143  // used by array operator[] and iterators to get reference types.
144  template <typename Reference, typename TPtr>
145  inline __device__ __host__ Reference access(boost::type<Reference>,index idx,TPtr base, const index* strides) const
146  {
147  BOOST_ASSERT(size_type(idx < boost::mpl::at<vector,boost::mpl::int_<0>>::type::value));
148  return *(base + idx * strides[0]);
149  }
150 
151  __device__ __host__ value_accessor_one_openfpm() { }
152  __device__ __host__ ~value_accessor_one_openfpm() { }
153 };
154 
155 
157 // choose value accessor begins
158 //
159 
160 template <typename T, std::size_t NumDims,typename vector>
162 {
164 };
165 
166 template <typename T,typename vector>
168 {
170 };
171 
172 template <typename T, typename NumDims, typename vector>
174 {
175  BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims::value);
176 
177  typedef typename
178  boost::mpl::eval_if_c<(dimensionality == 1),
181  >::type type;
182 };
183 
184 
185 template <class T, class NumDims, typename vector>
187 {};
188 
189 //
190 // choose value accessor ends
192 
193 // Due to some imprecision in the C++ Standard,
194 // MSVC 2010 is broken in debug mode: it requires
195 // that an Output Iterator have output_iterator_tag in its iterator_category if
196 // that iterator is not bidirectional_iterator or random_access_iterator.
197 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
198 struct mutable_iterator_tag
199  : boost::random_access_traversal_tag, std::input_iterator_tag
200 {
201  operator std::output_iterator_tag() const {
202  return std::output_iterator_tag();
203  }
204 };
205 #endif
206 
207 
209 // multi_array_base
211 template <typename T, std::size_t NumDims, typename vector>
212 class multi_array_impl_base_openfpm: public value_accessor_generator_openfpm<T,boost::mpl::size_t<NumDims>,vector>::type
213 {
215 public:
216 
217  typedef typename types::index index;
218  typedef typename types::size_type size_type;
219  typedef typename types::element element;
220  typedef typename types::value_type value_type;
221  typedef typename types::reference reference;
222  typedef typename types::const_reference const_reference;
223 
224  template <std::size_t NDims>
225  struct subarray
226  {
228  };
229 
230  template <std::size_t NDims>
232  {
234  };
235 
236  template <std::size_t NDims>
238  {
240  };
241 
242  template <std::size_t NDims>
244  {
245  public:
247  };
248 
249 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
250  // Deal with VC 2010 output_iterator_tag requirement
252  mutable_iterator_tag> iterator;
253 #else
255  boost::random_access_traversal_tag> iterator;
256 #endif
258  boost::random_access_traversal_tag> const_iterator;
259 
260  typedef ::boost::reverse_iterator<iterator> reverse_iterator;
261  typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
262 
263  BOOST_STATIC_CONSTANT(std::size_t, dimensionality = NumDims);
264 
265 protected:
266 
267  __device__ __host__ multi_array_impl_base_openfpm() { }
268  __device__ __host__ ~multi_array_impl_base_openfpm() { }
269 
270 
271  template <typename Stride_list, typename Extent_type>
272  void compute_strides(Stride_list& stride_list, Extent_type& extent,
273  const general_storage_order<NumDims>& storage)
274  {
275  // invariant: stride = the stride for dimension n
276  index stride = 1;
277  for (size_type n = 0; n != NumDims; ++n)
278  {
279  // The stride for this dimension is the product of the
280  // lengths of the ranks minor to it.
281  stride_list[storage.ordering(n)] = stride;
282 
283  if (storage.ordering(n) == 0)
284  {stride *= extent;}
285  else
286  {
287  switch(storage.ordering(n))
288  {
289  case 1:
291  break;
292  case 2:
294  break;
295  case 3:
297  break;
298  case 4:
300  break;
301  case 5:
303  break;
304  case 6:
306  break;
307  case 7:
309  break;
310  case 8:
312  break;
313  case 9:
315  break;
316  case 10:
318  break;
319  case 11:
321  break;
322  case 12:
324  break;
325  case 13:
327  break;
328  case 14:
330  break;
331  case 15:
333  break;
334  }
335  }
336  }
337  }
338 
339  // Used by operator() in our array classes
340  template <typename Reference, typename IndexList, typename TPtr>
341  Reference access_element(boost::type<Reference>,
342  const IndexList& indices,
343  TPtr base,
344  const size_type* extents,
345  const index* strides,
346  const index* index_bases) const
347  {
348  boost::function_requires<
349  boost::CollectionConcept<IndexList> >();
350  ignore_unused_variable_warning(index_bases);
351  ignore_unused_variable_warning(extents);
352 #ifdef SE_CLASS1
353  for (size_type i = 0; i != NumDims; ++i)
354  {
355  BOOST_ASSERT(indices[i] - index_bases[i] >= 0);
356  BOOST_ASSERT(size_type(indices[i] - index_bases[i]) < extents[i]);
357  }
358 #endif
359 
360  index offset = 0;
361  {
362  typename IndexList::const_iterator i = indices.begin();
363  size_type n = 0;
364  while (n != NumDims)
365  {
366  offset += (*i) * strides[n];
367  ++n;
368  ++i;
369  }
370  }
371  return base[offset];
372  }
373 };
374 
375 } // namespace multi_array
376 } // namespace detail
377 
378 } // namespace openfpm
379 
380 
381 #endif /* MULTI_ARRAY_REF_OPENFPM_BASE_HPP_ */
convert a type into constant type
Definition: aggregate.hpp:292
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
This class is a trick to indicate the compiler a specific specialization pattern.
Definition: memory_c.hpp:239