HCC
HCC is a single-source, C/C++ compiler for heterogeneous computing. It's optimized with HSA (http://www.hsafoundation.com/).
kalmar_index.h
1 #pragma once
2 
3 //forward declaration
4 namespace Concurrency {
5 template <int N> class extent;
6 } // namespace Concurrency
7 
8 //forward declaration
9 namespace hc {
10 template <int N> class extent;
11 } // namespace hc
12 
13 namespace Kalmar {
14 
16 template <int...> struct __indices {};
17 
18 template <int _Sp, class _IntTuple, int _Ep>
19 struct __make_indices_imp;
20 
21 template <int _Sp, int ..._Indices, int _Ep>
22 struct __make_indices_imp<_Sp, __indices<_Indices...>, _Ep> {
23  typedef typename __make_indices_imp<_Sp+1, __indices<_Indices..., _Sp>, _Ep>::type type;
24 };
25 
26 template <int _Ep, int ..._Indices>
27 struct __make_indices_imp<_Ep, __indices<_Indices...>, _Ep> {
28  typedef __indices<_Indices...> type;
29 };
30 
31 template <int _Ep, int _Sp = 0>
32 struct __make_indices {
33  static_assert(_Sp <= _Ep, "__make_indices input error");
34  typedef typename __make_indices_imp<_Sp, __indices<>, _Ep>::type type;
35 };
36 
37 template <int _Ip>
38 class __index_leaf {
39  int __idx;
40  int dummy;
41 public:
42  explicit __index_leaf(int __t) restrict(amp,cpu) : __idx(__t) {}
43 
44  __index_leaf& operator=(const int __t) restrict(amp,cpu) {
45  __idx = __t;
46  return *this;
47  }
48  __index_leaf& operator+=(const int __t) restrict(amp,cpu) {
49  __idx += __t;
50  return *this;
51  }
52  __index_leaf& operator-=(const int __t) restrict(amp,cpu) {
53  __idx -= __t;
54  return *this;
55  }
56  __index_leaf& operator*=(const int __t) restrict(amp,cpu) {
57  __idx *= __t;
58  return *this;
59  }
60  __index_leaf& operator/=(const int __t) restrict(amp,cpu) {
61  __idx /= __t;
62  return *this;
63  }
64  __index_leaf& operator%=(const int __t) restrict(amp,cpu) {
65  __idx %= __t;
66  return *this;
67  }
68  int& get() restrict(amp,cpu) { return __idx; }
69  const int& get() const restrict(amp,cpu) { return __idx; }
70 };
71 
72 template <class _Indx> struct index_impl;
73 
74 template <int ...N>
75 struct index_impl<__indices<N...> > : public __index_leaf<N>... {
76  index_impl() restrict(amp,cpu) : __index_leaf<N>(0)... {}
77 
78  template<class ..._Up>
79  explicit index_impl(_Up... __u) restrict(amp,cpu)
80  : __index_leaf<N>(__u)... {}
81 
82  index_impl(const index_impl& other) restrict(amp,cpu)
83  : index_impl(static_cast<const __index_leaf<N>&>(other).get()...) {}
84 
85  index_impl(int component) restrict(amp,cpu)
86  : __index_leaf<N>(component)... {}
87  index_impl(int components[]) restrict(amp,cpu)
88  : __index_leaf<N>(components[N])... {}
89  index_impl(const int components[]) restrict(amp,cpu)
90  : __index_leaf<N>(components[N])... {}
91 
92  template<class ..._Tp>
93  inline void __swallow(_Tp...) restrict(amp,cpu) {}
94 
95  int operator[] (unsigned int c) const restrict(amp,cpu) {
96  return static_cast<const __index_leaf<0>&>(*((__index_leaf<0> *)this + c)).get();
97  }
98  int& operator[] (unsigned int c) restrict(amp,cpu) {
99  return static_cast<__index_leaf<0>&>(*((__index_leaf<0> *)this + c)).get();
100  }
101  index_impl& operator=(const index_impl& __t) restrict(amp,cpu) {
102  __swallow(__index_leaf<N>::operator=(static_cast<const __index_leaf<N>&>(__t).get())...);
103  return *this;
104  }
105  index_impl& operator+=(const index_impl& __t) restrict(amp,cpu) {
106  __swallow(__index_leaf<N>::operator+=(static_cast<const __index_leaf<N>&>(__t).get())...);
107  return *this;
108  }
109  index_impl& operator-=(const index_impl& __t) restrict(amp,cpu) {
110  __swallow(__index_leaf<N>::operator-=(static_cast<const __index_leaf<N>&>(__t).get())...);
111  return *this;
112  }
113  index_impl& operator*=(const index_impl& __t) restrict(amp,cpu) {
114  __swallow(__index_leaf<N>::operator*=(static_cast<const __index_leaf<N>&>(__t).get())...);
115  return *this;
116  }
117  index_impl& operator/=(const index_impl& __t) restrict(amp,cpu) {
118  __swallow(__index_leaf<N>::operator/=(static_cast<const __index_leaf<N>&>(__t).get())...);
119  return *this;
120  }
121  index_impl& operator%=(const index_impl& __t) restrict(amp,cpu) {
122  __swallow(__index_leaf<N>::operator%=(static_cast<const __index_leaf<N>&>(__t).get())...);
123  return *this;
124  }
125  index_impl& operator+=(const int __t) restrict(amp,cpu) {
126  __swallow(__index_leaf<N>::operator+=(__t)...);
127  return *this;
128  }
129  index_impl& operator-=(const int __t) restrict(amp,cpu) {
130  __swallow(__index_leaf<N>::operator-=(__t)...);
131  return *this;
132  }
133  index_impl& operator*=(const int __t) restrict(amp,cpu) {
134  __swallow(__index_leaf<N>::operator*=(__t)...);
135  return *this;
136  }
137  index_impl& operator/=(const int __t) restrict(amp,cpu) {
138  __swallow(__index_leaf<N>::operator/=(__t)...);
139  return *this;
140  }
141  index_impl& operator%=(const int __t) restrict(amp,cpu) {
142  __swallow(__index_leaf<N>::operator%=(__t)...);
143  return *this;
144  }
145 };
146 
147 template <int N, typename _Tp>
148 struct index_helper
149 {
150  static inline void set(_Tp& now) restrict(amp,cpu) {
151  now[N - 1] = amp_get_global_id(_Tp::rank - N);
152  index_helper<N - 1, _Tp>::set(now);
153  }
154  static inline bool equal(const _Tp& _lhs, const _Tp& _rhs) restrict(amp,cpu) {
155  return (_lhs[N - 1] == _rhs[N - 1]) &&
156  (index_helper<N - 1, _Tp>::equal(_lhs, _rhs));
157  }
158  static inline int count_size(const _Tp& now) restrict(amp,cpu) {
159  return now[N - 1] * index_helper<N - 1, _Tp>::count_size(now);
160  }
161 };
162 
163 template<typename _Tp>
164 struct index_helper<1, _Tp>
165 {
166  static inline void set(_Tp& now) restrict(amp,cpu) {
167  now[0] = amp_get_global_id(_Tp::rank - 1);
168  }
169  static inline bool equal(const _Tp& _lhs, const _Tp& _rhs) restrict(amp,cpu) {
170  return (_lhs[0] == _rhs[0]);
171  }
172  static inline int count_size(const _Tp& now) restrict(amp,cpu) {
173  return now[0];
174  }
175 };
176 
177 template <int N, typename _Tp1, typename _Tp2>
178 struct amp_helper
179 {
180  static bool inline contains(const _Tp1& idx, const _Tp2& ext) restrict(amp,cpu) {
181  return idx[N - 1] >= 0 && idx[N - 1] < ext[N - 1] &&
182  amp_helper<N - 1, _Tp1, _Tp2>::contains(idx, ext);
183  }
184 
185  static bool inline contains(const _Tp1& idx, const _Tp2& ext,const _Tp2& ext2) restrict(amp,cpu) {
186  return idx[N - 1] >= 0 && ext[N - 1] > 0 && (idx[N - 1] + ext[N - 1]) <= ext2[N - 1] &&
187  amp_helper<N - 1, _Tp1, _Tp2>::contains(idx, ext,ext2);
188  }
189 
190  static int inline flatten(const _Tp1& idx, const _Tp2& ext) restrict(amp,cpu) {
191  return idx[N - 1] + ext[N - 1] * amp_helper<N - 1, _Tp1, _Tp2>::flatten(idx, ext);
192  }
193  static void inline minus(const _Tp1& idx, _Tp2& ext) restrict(amp,cpu) {
194  ext.base_ -= idx.base_;
195  }
196 };
197 
198 template <typename _Tp1, typename _Tp2>
199 struct amp_helper<1, _Tp1, _Tp2>
200 {
201  static bool inline contains(const _Tp1& idx, const _Tp2& ext) restrict(amp,cpu) {
202  return idx[0] >= 0 && idx[0] < ext[0];
203  }
204 
205  static bool inline contains(const _Tp1& idx, const _Tp2& ext,const _Tp2& ext2) restrict(amp,cpu) {
206  return idx[0] >= 0 && ext[0] > 0 && (idx[0] + ext[0]) <= ext2[0] ;
207  }
208 
209  static int inline flatten(const _Tp1& idx, const _Tp2& ext) restrict(amp,cpu) {
210  return idx[0];
211  }
212  static void inline minus(const _Tp1& idx, _Tp2& ext) restrict(amp,cpu) {
213  ext.base_ -= idx.base_;
214  }
215 };
225 template <int N>
226 class index {
227 public:
231  static const int rank = N;
232 
236  typedef int value_type;
237 
242  index() restrict(amp,cpu) : base_() {
243  static_assert( N>0, "rank should bigger than 0 ");
244  };
245 
253  index(const index& other) restrict(amp,cpu)
254  : base_(other.base_) {}
255 
265  explicit index(int i0) restrict(amp,cpu)
266  : base_(i0) {}
267 
268  template <typename ..._Tp>
269  explicit index(_Tp ... __t) restrict(amp,cpu)
270  : base_(__t...) {
271  static_assert(sizeof...(_Tp) <= 3, "Explicit constructor with rank greater than 3 is not allowed");
272  static_assert(sizeof...(_Tp) == N, "rank should be consistency");
273  }
274 
285  explicit index(const int components[]) restrict(amp,cpu)
286  : base_(components) {}
287 
296  // FIXME: this function is not defined in C++AMP specification.
297  explicit index(int components[]) restrict(amp,cpu)
298  : base_(components) {}
299 
307  index& operator=(const index& other) restrict(amp,cpu) {
308  base_.operator=(other.base_);
309  return *this;
310  }
311 
319  int operator[] (unsigned int c) const restrict(amp,cpu) {
320  return base_[c];
321  }
322  int& operator[] (unsigned int c) restrict(amp,cpu) {
323  return base_[c];
324  }
325 
338  // FIXME: the signature is not entirely the same as defined in:
339  // C++AMP spec v1.2 #1137
340  bool operator== (const index& other) const restrict(amp,cpu) {
341  return index_helper<N, index<N> >::equal(*this, other);
342  }
343  bool operator!= (const index& other) const restrict(amp,cpu) {
344  return !(*this == other);
345  }
346 
357  index& operator+=(const index& rhs) restrict(amp,cpu) {
358  base_.operator+=(rhs.base_);
359  return *this;
360  }
361  index& operator-=(const index& rhs) restrict(amp,cpu) {
362  base_.operator-=(rhs.base_);
363  return *this;
364  }
365 
366  // FIXME: this function is not defined in C++AMP specification.
367  index& operator*=(const index& __r) restrict(amp,cpu) {
368  base_.operator*=(__r.base_);
369  return *this;
370  }
371  // FIXME: this function is not defined in C++AMP specification.
372  index& operator/=(const index& __r) restrict(amp,cpu) {
373  base_.operator/=(__r.base_);
374  return *this;
375  }
376  // FIXME: this function is not defined in C++AMP specification.
377  index& operator%=(const index& __r) restrict(amp,cpu) {
378  base_.operator%=(__r.base_);
379  return *this;
380  }
381 
392  index& operator+=(int value) restrict(amp,cpu) {
393  base_.operator+=(value);
394  return *this;
395  }
396  index& operator-=(int value) restrict(amp,cpu) {
397  base_.operator-=(value);
398  return *this;
399  }
400  index& operator*=(int value) restrict(amp,cpu) {
401  base_.operator*=(value);
402  return *this;
403  }
404  index& operator/=(int value) restrict(amp,cpu) {
405  base_.operator/=(value);
406  return *this;
407  }
408  index& operator%=(int value) restrict(amp,cpu) {
409  base_.operator%=(value);
410  return *this;
411  }
412 
423  index& operator++() restrict(amp,cpu) {
424  base_.operator+=(1);
425  return *this;
426  }
427  index operator++(int) restrict(amp,cpu) {
428  index ret = *this;
429  base_.operator+=(1);
430  return ret;
431  }
432  index& operator--() restrict(amp,cpu) {
433  base_.operator-=(1);
434  return *this;
435  }
436  index operator--(int) restrict(amp,cpu) {
437  index ret = *this;
438  base_.operator-=(1);
439  return ret;
440  }
441 
444 private:
445  typedef index_impl<typename __make_indices<N>::type> base;
446  base base_;
447  template <int T> friend class Concurrency::extent;
448  template <int T> friend class hc::extent;
449  template <int K, typename Q> friend struct index_helper;
450  template <int K, typename Q1, typename Q2> friend struct amp_helper;
451 
452 public:
453  __attribute__((annotate("__cxxamp_opencl_index")))
454  void __cxxamp_opencl_index() restrict(amp,cpu)
455 #if __KALMAR_ACCELERATOR__ == 1
456  {
457  index_helper<N, index<N>>::set(*this);
458  }
459 #elif __KALMAR_ACCELERATOR__ == 2 || __KALMAR_CPU__ == 2
460  {}
461 #else
462  ;
463 #endif
464 };
465 
467 // explicit instantions
469 template class index<1>;
470 template class index<2>;
471 template class index<3>;
472 
474 // operators for index<N>
476 
489 // FIXME: the signature is not entirely the same as defined in:
490 // C++AMP spec v1.2 #1138
491 template <int N>
492 index<N> operator+(const index<N>& lhs, const index<N>& rhs) restrict(amp,cpu) {
493  index<N> __r = lhs;
494  __r += rhs;
495  return __r;
496 }
497 template <int N>
498 index<N> operator-(const index<N>& lhs, const index<N>& rhs) restrict(amp,cpu) {
499  index<N> __r = lhs;
500  __r -= rhs;
501  return __r;
502 }
503 
520 // FIXME: the signature is not entirely the same as defined in:
521 // C++AMP spec v1.2 #1141
522 template <int N>
523 index<N> operator+(const index<N>& idx, int value) restrict(amp,cpu) {
524  index<N> __r = idx;
525  __r += value;
526  return __r;
527 }
528 template <int N>
529 index<N> operator+(int value, const index<N>& idx) restrict(amp,cpu) {
530  index<N> __r = idx;
531  __r += value;
532  return __r;
533 }
534 template <int N>
535 index<N> operator-(const index<N>& idx, int value) restrict(amp,cpu) {
536  index<N> __r = idx;
537  __r -= value;
538  return __r;
539 }
540 template <int N>
541 index<N> operator-(int value, const index<N>& idx) restrict(amp,cpu) {
542  index<N> __r(value);
543  __r -= idx;
544  return __r;
545 }
546 template <int N>
547 index<N> operator*(const index<N>& idx, int value) restrict(amp,cpu) {
548  index<N> __r = idx;
549  __r *= value;
550  return __r;
551 }
552 template <int N>
553 index<N> operator*(int value, const index<N>& idx) restrict(amp,cpu) {
554  index<N> __r(value);
555  __r *= idx;
556  return __r;
557 }
558 template <int N>
559 index<N> operator/(const index<N>& idx, int value) restrict(amp,cpu) {
560  index<N> __r = idx;
561  __r /= value;
562  return __r;
563 }
564 template <int N>
565 index<N> operator/(int value, const index<N>& idx) restrict(amp,cpu) {
566  index<N> __r(value);
567  __r /= idx;
568  return __r;
569 }
570 template <int N>
571 index<N> operator%(const index<N>& idx, int value) restrict(amp,cpu) {
572  index<N> __r = idx;
573  __r %= value;
574  return __r;
575 }
576 template <int N>
577 index<N> operator%(int value, const index<N>& idx) restrict(amp,cpu) {
578  index<N> __r(value);
579  __r %= idx;
580  return __r;
581 }
582 
586 } // namespace Kalmar
587 
index & operator++()
For a given operator , produces the same effect as (*this) = (*this) 1;.
Definition: kalmar_index.h:423
index(int components[])
Constructs an index<N> with the coordinate values provided the array of int component values...
Definition: kalmar_index.h:297
index & operator--()
For a given operator , produces the same effect as (*this) = (*this) 1;.
Definition: kalmar_index.h:432
extent< N > operator/(const extent< N > &ext, int value)
Binary arithmetic operations that produce a new extent<N> that is the result of performing the corres...
Definition: amp.h:4651
index & operator*=(int value)
For a given operator , produces the same effect as (*this) = (*this) value; The return value is "*th...
Definition: kalmar_index.h:400
index & operator/=(int value)
For a given operator , produces the same effect as (*this) = (*this) value; The return value is "*th...
Definition: kalmar_index.h:404
Represents a unique position in N-dimensional space.
Definition: hc.hpp:58
C++ AMP namespace.
Definition: amp.h:25
extent< N > operator+(const extent< N > &lhs, const extent< N > &rhs)
Adds (or subtracts) two objects of extent<N> to form a new extent.
Definition: amp.h:4584
index & operator=(const index &other)
Assigns the component values of "other" to this index<N> object.
Definition: kalmar_index.h:307
namespace for internal classes of Kalmar compiler / runtime
Definition: hc.hpp:42
index & operator%=(int value)
For a given operator , produces the same effect as (*this) = (*this) value; The return value is "*th...
Definition: kalmar_index.h:408
int value_type
The element type of index<N>.
Definition: kalmar_index.h:236
index operator++(int)
For a given operator , produces the same effect as (*this) = (*this) 1;.
Definition: kalmar_index.h:427
index & operator%=(const index &__r)
For a given operator , produces the same effect as (*this) = (*this) rhs; The return value is "*this...
Definition: kalmar_index.h:377
extent< N > operator*(const extent< N > &ext, int value)
Binary arithmetic operations that produce a new extent<N> that is the result of performing the corres...
Definition: amp.h:4639
extent< N > operator-(const extent< N > &lhs, const extent< N > &rhs)
Adds (or subtracts) two objects of extent<N> to form a new extent.
Definition: amp.h:4590
index(_Tp...__t)
Constructs an index<N> with the coordinate values provided by .
Definition: kalmar_index.h:269
index & operator*=(const index &__r)
For a given operator , produces the same effect as (*this) = (*this) rhs; The return value is "*this...
Definition: kalmar_index.h:367
Represents a unique position in N-dimensional space.
Definition: amp.h:31
index & operator+=(const index &rhs)
For a given operator , produces the same effect as (*this) = (*this) rhs; The return value is "*this...
Definition: kalmar_index.h:357
Represents a unique position in N-dimensional space.
Definition: kalmar_index.h:226
index & operator-=(const index &rhs)
For a given operator , produces the same effect as (*this) = (*this) rhs; The return value is "*this...
Definition: kalmar_index.h:361
extent< N > operator%(const extent< N > &ext, int value)
Binary arithmetic operations that produce a new extent<N> that is the result of performing the corres...
Definition: amp.h:4663
index(const index &other)
Copy constructor.
Definition: kalmar_index.h:253
index & operator+=(int value)
For a given operator , produces the same effect as (*this) = (*this) value; The return value is "*th...
Definition: kalmar_index.h:392
index(int i0)
Constructs an index<N> with the coordinate values provided by .
Definition: kalmar_index.h:265
index()
Default constructor.
Definition: kalmar_index.h:242
index operator--(int)
For a given operator , produces the same effect as (*this) = (*this) 1;.
Definition: kalmar_index.h:436
index & operator/=(const index &__r)
For a given operator , produces the same effect as (*this) = (*this) rhs; The return value is "*this...
Definition: kalmar_index.h:372
Heterogeneous C++ (HC) namespace.
Definition: grid_launch.h:10
index(const int components[])
Constructs an index<N> with the coordinate values provided the array of int component values...
Definition: kalmar_index.h:285
index & operator-=(int value)
For a given operator , produces the same effect as (*this) = (*this) value; The return value is "*th...
Definition: kalmar_index.h:396