OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
multi_array_ref_subarray_openfpm.hpp
1 /*
2  * multi_array_ref_subarray_openfpm.hpp
3  *
4  * Created on: Jul 1, 2018
5  * Author: i-bird
6  */
7 
8 #ifndef MULTI_ARRAY_REF_SUBARRAY_OPENFPM_HPP_
9 #define MULTI_ARRAY_REF_SUBARRAY_OPENFPM_HPP_
10 
11 #include "multi_array_view_openfpm.hpp"
12 #include "multi_array_ref_base_openfpm.hpp"
13 
18 template<typename vmpl>
19 struct subar_dim
20 {
21  typedef typename boost::mpl::at<vmpl,boost::mpl::int_<0>>::type type;
22 };
23 
24 namespace openfpm {
25 namespace detail {
26 namespace multi_array {
27 
28 //
29 // const_sub_array
30 // multi_array's proxy class to allow multiple overloads of
31 // operator[] in order to provide a clean multi-dimensional array
32 // interface.
33 template <typename T, std::size_t NumDims, typename vector, typename TPtr>
34 class const_sub_array_openfpm : public openfpm::detail::multi_array::multi_array_impl_base_openfpm<T,NumDims,vector>
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 
43 public:
44 
45  typedef typename super_type::value_type value_type;
46  typedef typename super_type::const_reference const_reference;
47  typedef typename super_type::const_iterator const_iterator;
48  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
49  typedef typename super_type::element element;
50  typedef typename super_type::size_type size_type;
51  typedef typename super_type::difference_type difference_type;
52  typedef typename super_type::index index;
53 
54  // template typedefs
55  template <std::size_t NDims>
58  };
59 
60  template <std::size_t NDims>
61  struct array_view {
63  };
64 
65  // Allow default copy constructor as well.
66 
67  template <typename Ovector>
69  :base_(rhs.base_), strides_(rhs.strides_)
70  {}
71 
72  // const_sub_array always returns const types, regardless of its own
73  // constness.
74  inline __device__ __host__ const_reference operator[](index idx) const
75  {
76  return super_type::access(boost::type<const_reference>(),idx,strides(),base_);
77  }
78 
79  template <typename IndexList>
80  const element& operator()(const IndexList& indices) const
81  {
82  boost::function_requires<boost::CollectionConcept<IndexList> >();
83  return super_type::access_element(boost::type<const element&>(),
84  indices,origin(),strides());
85  }
86 
87  // see generate_array_view in base.hpp
88  template <int NDims>
89  __device__ __host__ typename const_array_view<NDims>::type
90  operator[](const boost::detail::multi_array::index_gen<NumDims,NDims>& indices) const
91  {
92  typedef typename const_array_view<NDims>::type return_type;
93  return super_type::generate_array_view(boost::type<return_type>(),
94  indices,
95  base_);
96  }
97 
98  template <typename OPtr>
99  bool operator!=(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
100  return !(*this == rhs);
101  }
102 
103  template <typename OPtr>
104  bool operator>(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
105  return rhs < *this;
106  }
107 
108  template <typename OPtr>
109  bool operator<=(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
110  return !(*this > rhs);
111  }
112 
113  template <typename OPtr>
114  bool operator>=(const const_sub_array_openfpm<T,NumDims,OPtr>& rhs) const {
115  return !(*this < rhs);
116  }
117 
118  TPtr origin() const { return base_; }
119  inline __host__ __device__ size_type size() const { return boost::mpl::at<vector,boost::mpl::int_<0>>::type::value; }
120  size_type max_size() const { return num_elements(); }
121  bool empty() const { return size() == 0; }
122  inline __device__ __host__ size_type num_dimensions() const { return NumDims; }
123  inline __host__ __device__ const index* strides() const { return strides_; }
124 
125  size_type num_elements() const
126  {
127  return size_ct::type::value;
128  }
129 
130  __device__ __host__ const_sub_array_openfpm (TPtr base, const index* strides)
131  :base_(base), strides_(strides)
132  {}
133 
134 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
135 protected:
136  template <typename,std::size_t,typename> friend class value_accessor_n_openfpm;
137  template <typename,std::size_t,typename,typename> friend class const_sub_array_openfpm;
138 #else
139 public: // Should be protected
140 #endif
141 
142 
143  TPtr base_;
144  const index* strides_;
145 private:
146  // const_sub_array cannot be assigned to (no deep copies!)
147  const_sub_array_openfpm& operator=(const const_sub_array_openfpm&);
148 };
149 
150 //
151 // sub_array
152 // multi_array's proxy class to allow multiple overloads of
153 // operator[] in order to provide a clean multi-dimensional array
154 // interface.
155 template <typename T, std::size_t NumDims, typename vector>
156 class sub_array_openfpm : public const_sub_array_openfpm<T,NumDims,vector,T*>
157 {
158  typedef const_sub_array_openfpm<T,NumDims,vector,T*> super_type;
159 public:
160  typedef typename super_type::element element;
161  typedef typename super_type::reference reference;
162  typedef typename super_type::index index;
163  typedef typename super_type::size_type size_type;
164  typedef typename super_type::iterator iterator;
165  typedef typename super_type::reverse_iterator reverse_iterator;
166  typedef typename super_type::const_reference const_reference;
167  typedef typename super_type::const_iterator const_iterator;
168  typedef typename super_type::const_reverse_iterator const_reverse_iterator;
169  typedef int yes_is_multi_array;
170 
171  // template typedefs
172  template <std::size_t NDims>
175  };
176 
177  template <std::size_t NDims>
178  struct array_view {
180  };
181 
182  // Assignment from other ConstMultiArray types.
183  template <typename ConstMultiArray>
184  __device__ __host__ inline sub_array_openfpm& operator=(const ConstMultiArray& other)
185  {
186 #ifdef SE_CLASS1
187 
188  // make sure the dimensions agree
189  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
190 
191 #endif
192  // iterator-based copy
193 // std::copy(other.begin(),other.end(),begin());
194 
195  for (int i = 0 ; i < (int)other.size() ; i++)
196  {this->operator[](i) = other[i];}
197  return *this;
198  }
199 
200  __device__ __host__ sub_array_openfpm& operator=(const sub_array_openfpm& other)
201  {
202 #ifdef SE_CLASS1
203  // make sure the dimensions agree
204  BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
205 // BOOST_ASSERT(std::equal(other.shape(),
206 // other.shape()+this->num_dimensions(),
207 // this->shape()));
208 #endif
209  // iterator-based copy
210  //std::copy(other.begin(),other.end(),begin());
211 
212  for (int i = 0 ; i < (int)other.size() ; i++)
213  {this->operator[](i) = other[i];}
214  return *this;
215  }
216 
217  __device__ __host__ T* origin_mutable() const { return const_cast<T*>(this->base_); }
218  __device__ __host__ T* origin() { return this->base_; }
219  __device__ __host__ const T* origin() const { return this->base_; }
220 
221  __device__ __host__ reference operator[](index idx) {
222  return super_type::access(boost::type<reference>(),
223  idx,
224  this->strides(),
225  this->base_);
226  }
227 
228  __device__ __host__ iterator begin()
229  {
230  return iterator(*this->index_bases(),origin(),
231  this->shape(),this->strides(),this->index_bases());
232  }
233 
234  __device__ __host__ iterator end()
235  {
236  return iterator(*this->index_bases()+(index)*this->shape(),origin(),
237  this->shape(),this->strides(),this->index_bases());
238  }
239 
240  // RG - rbegin() and rend() written naively to thwart MSVC ICE.
241  reverse_iterator rbegin() {
242  reverse_iterator ri(end());
243  return ri;
244  }
245 
246  reverse_iterator rend() {
247  reverse_iterator ri(begin());
248  return ri;
249  }
250 
251  //
252  // proxies
253  //
254 
255  template <class IndexList>
256  const element& operator()(const IndexList& indices) const {
257  boost::function_requires<
258  boost::CollectionConcept<IndexList> >();
259  return super_type::operator()(indices);
260  }
261 
262  const_reference __device__ __host__ operator[](index idx) const {
263  return super_type::operator[](idx);
264  }
265 
266  const_iterator begin() const {
267  return super_type::begin();
268  }
269 
270  const_iterator end() const {
271  return super_type::end();
272  }
273 
274  const_reverse_iterator rbegin() const {
275  return super_type::rbegin();
276  }
277 
278  const_reverse_iterator rend() const {
279  return super_type::rend();
280  }
281 
282 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
283 private:
284  template <typename,std::size_t,typename> friend class value_accessor_n_openfpm;
285 #endif
286 public: // should be private
287 
288  inline __device__ __host__ sub_array_openfpm (T* base,
289  const index* strides)
290  :super_type(base,strides)
291  {}
292 
293 };
294 
295 } // namespace multi_array
296 } // namespace detail
297 //
298 // traits classes to get sub_array types
299 //
300 template <typename Array, int N, typename vector>
302  typedef typename Array::element element;
303 public:
305 };
306 
307 template <typename Array, int N, typename vector>
309  typedef typename Array::element element;
310 public:
312 };
313 } // namespace boost
314 
315 
316 #endif /* MULTI_ARRAY_REF_SUBARRAY_OPENFPM_HPP_ */
convert a type into constant type
Definition: aggregate.hpp:292
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
return the dimension of the sub_array
This class is a trick to indicate the compiler a specific specialization pattern.
Definition: memory_c.hpp:239