31 #ifndef HERMES_COMMON_INDEX_H
32 #define HERMES_COMMON_INDEX_H
51 static_assert(std::is_same<T, i8>::value || std::is_same<T, i16>::value ||
52 std::is_same<T, i32>::value || std::is_same<T, i64>::value,
53 "Index2 must hold an integer type!");
59 #define ARITHMETIC_OP(OP) \
60 template<typename U> \
61 HERMES_DEVICE_CALLABLE friend Index2<T> operator OP (const Size2<U> &b, const Index2<T> &a) { \
62 return Index2<T>(b.width OP a.i, b.height OP a.j); } \
63 HERMES_DEVICE_CALLABLE friend Index2<T> operator OP (const Index2<T> &b, const T &a) { \
64 return Index2<T>(b.i OP a, b.j OP a); }
80 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
83 return std::abs(a.
i - b.
i) + std::abs(a.
j - b.
j);
87 #define MATH_OP(NAME, OP) \
88 HERMES_DEVICE_CALLABLE friend Index2<T> NAME(const Index2<T>& a, const Index2<T>& b) { \
89 return Index2<T>(OP(a.i, b.i), OP(a.j, b.j)); }
90 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
94 MATH_OP(max, std::max)
95 MATH_OP(min, std::min)
131 #define ARITHMETIC_OP(OP) \
132 HERMES_DEVICE_CALLABLE Index2<T>& operator OP##= (const Index2<T> &b) { \
133 i OP##= b.i; j OP##= b.j; return *this; } \
134 HERMES_DEVICE_CALLABLE Index2<T> operator OP (const Index2<T>& b) const { \
135 return {i OP b.i, j OP b.j}; } \
136 template<typename U> \
137 HERMES_DEVICE_CALLABLE Index2<T>& operator OP##= (const Size2<U> &b) { \
138 i OP##= static_cast<T>(b.width); j OP##= static_cast<T>(b.height); return *this; } \
139 template<typename U> \
140 HERMES_DEVICE_CALLABLE Index2<T> operator OP (const Size2<U>& b) const { \
141 return {i OP static_cast<T>(b.width), j OP static_cast<T>(b.height)}; }
148 #define RELATIONAL_OP(OP, CO) \
149 HERMES_DEVICE_CALLABLE bool operator OP (const Index2<T> &b) const { \
150 return i OP b.i CO j OP b.j; } \
151 template<typename U> \
152 HERMES_DEVICE_CALLABLE bool operator OP (const Size2<U>& b) const { \
153 return i OP static_cast<T>(b.width) CO j OP static_cast<T>(b.height); }
154 RELATIONAL_OP(==, &&)
155 RELATIONAL_OP(!=, ||)
156 RELATIONAL_OP(>=, &&)
157 RELATIONAL_OP(<=, &&)
188 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
191 i = std::max(0, std::min(
i,
static_cast<T
>(s.
width)));
192 j = std::max(0, std::min(
j,
static_cast<T
>(s.
height)));
219 : index_(lower), lower_(lower), upper_(upper) {}
225 : index_(start), lower_(lower), upper_(upper) {}
233 if (index_.i >= upper_.i) {
236 if (index_.j >= upper_.j)
249 auto size = upper_ - lower_;
250 return index_.j * size.i + index_.i;
257 return index_ == other.index_;
263 return index_ != other.index_;
292 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
294 Index2<T>(min(a.upper_.i, b.upper_.i), min(a.upper_.j, b.upper_.j)));
296 return {{std::max(a.lower_.i, b.lower_.i), std::max(a.lower_.j, b.lower_.j)},
297 {std::min(a.upper_.i, b.upper_.i), std::min(a.upper_.j, b.upper_.j)}};
308 lower_(
Index2<T>()), upper_(
Index2<T>(upper_i, upper_j)) {}
321 return ij >= lower_ && ij < upper_;
330 return lower_ == r.lower_ && upper_ == r.upper_;
349 auto d = upper_ - lower_;
363 static_assert(std::is_same<T, i8>::value || std::is_same<T, i16>::value ||
364 std::is_same<T, i32>::value || std::is_same<T, i64>::value,
365 "Index3 must hold an integer type!");
372 #define ARITHMETIC_OP(OP) \
373 template<typename U> \
374 HERMES_DEVICE_CALLABLE friend Index3<T> operator OP (const Size3<U> &b, const Index3<T> &a) { \
375 return Index3<T>(b.width OP a.i, b.height OP a.j, b.depth OP a.k); }
408 #define ARITHMETIC_OP(OP) \
409 HERMES_DEVICE_CALLABLE Index3<T>& operator OP##= (const Index3<T> &b) { \
410 i OP##= b.i; j OP##= b.j; k OP##= b.k; return *this; } \
411 HERMES_DEVICE_CALLABLE Index3<T> operator OP (const Index3<T>& b) const { \
412 return {i OP b.i, j OP b.j, k OP b.k}; } \
413 template<typename U> \
414 HERMES_DEVICE_CALLABLE Index3<T>& operator OP##= (const Size3<U> &b) { \
415 i OP##= b.width; j OP##= b.height; k OP##= b.depth; return *this; } \
416 template<typename U> \
417 HERMES_DEVICE_CALLABLE Index3<T> operator OP (const Size3<U>& b) const { \
418 return {i OP static_cast<T>(b.width), j OP static_cast<T>(b.height), \
419 k OP static_cast<T>(b.depth)}; }
426 #define RELATIONAL_OP(OP, CO) \
427 HERMES_DEVICE_CALLABLE bool operator OP (const Index3<T> &b) const { \
428 return i OP b.i CO j OP b.j CO k OP b.k; } \
429 template<typename U> \
430 HERMES_DEVICE_CALLABLE bool operator OP (const Size3<U>& b) const { \
431 return i OP static_cast<T>(b.width) CO \
432 j OP static_cast<T>(b.height) CO k OP static_cast<T>(b.depth); }
433 RELATIONAL_OP(==, &&)
434 RELATIONAL_OP(!=, ||)
435 RELATIONAL_OP(>=, &&)
436 RELATIONAL_OP(<=, &&)
466 : index_(start), lower_(lower), upper_(upper) {}
482 auto size = upper_ - lower_;
483 return index_.k * (size.i * size.j) + index_.j * size.i + index_.i;
489 if (index_.i >= upper_.i) {
492 if (index_.j >= upper_.j) {
495 if (index_.k >= upper_.k)
506 return index_ == other.index_;
512 return index_ != other.index_;
542 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
543 return {
Index3<T>(max(a.lower_.i, b.lower_.i), max(a.lower_.j, b.lower_.j),
544 max(a.lower_.k, b.lower_.k)),
545 Index3<T>(min(a.upper_.i, b.upper_.i), min(a.upper_.j, b.upper_.j),
546 min(a.upper_.k, b.upper_.k))};
548 return {{std::max(a.lower_.i, b.lower_.i), std::max(a.lower_.i, b.lower_.j),
549 std::max(a.lower_.k, b.lower_.k)},
550 {std::min(a.upper_.i, b.upper_.i), std::min(a.upper_.i, b.upper_.j),
551 std::min(a.upper_.k, b.upper_.k)}};
562 : lower_(
Index3<T>()), upper_(
Index3<T>(upper_i, upper_j, upper_k)) {}
570 upper_(
Index3<T>(upper.width, upper.height, upper.depth)) {}
574 : lower_(lower), upper_(upper) {}
586 auto size = upper_ - lower_;
600 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
601 return size3(std::abs(upper_[0] - lower_[0]),
602 std::abs(upper_[1] - lower_[1]),
603 std::abs(upper_[2] - lower_[2]));
605 return size3(std::abs(upper_[0] - lower_[0]),
606 std::abs(upper_[1] - lower_[1]),
607 std::abs(upper_[2] - lower_[2]));
623 std::ostream &operator<<(std::ostream &o,
const Index2<T> &ij) {
624 o <<
"Index[" << ij.
i <<
", " << ij.
j <<
"]";
632 std::ostream &operator<<(std::ostream &o,
const Index3<T> &ijk) {
633 o <<
"Index[" << ijk.
i <<
", " << ijk.
j <<
", " << ijk.
k <<
"]";
HERMES_DEVICE_CALLABLE Index2Iterator(Index2< T > lower, Index2< T > upper, Index2< T > start)
Construct a new Index2Iterator object.
Definition: index.h:224
HERMES_DEVICE_CALLABLE Index2Iterator & operator++()
Definition: index.h:231
HERMES_DEVICE_CALLABLE bool operator==(const Index2Iterator< T > &other) const
are equal? operator
Definition: index.h:256
HERMES_DEVICE_CALLABLE size_t flatIndex() const
Computes a flat index based on size.
Definition: index.h:248
HERMES_DEVICE_CALLABLE bool operator!=(const Index2Iterator< T > &other) const
are different? operator
Definition: index.h:262
HERMES_DEVICE_CALLABLE const Index2< T > & operator*() const
Definition: index.h:243
HERMES_DEVICE_CALLABLE Index2Iterator()
Default constructor.
Definition: index.h:214
HERMES_DEVICE_CALLABLE Index2Iterator(Index2< T > lower, Index2< T > upper)
Constructor.
Definition: index.h:218
Represents a closed-open range of indices [lower, upper)
Definition: index.h:283
HERMES_DEVICE_CALLABLE T area() const
Definition: index.h:348
HERMES_DEVICE_CALLABLE const Index2< T > & upper() const
Definition: index.h:346
HERMES_DEVICE_CALLABLE bool operator==(const Index2Range< T > &r) const
Definition: index.h:329
HERMES_DEVICE_CALLABLE bool contains(const Index2< T > &ij) const
Definition: index.h:320
HERMES_DEVICE_CALLABLE Index2Range(T upper_i, T upper_j)
Constructs an index range [0, {upper_i,upper_j})
Definition: index.h:307
HERMES_DEVICE_CALLABLE Index2Range(size2 upper)
Constructs an index range [0, upper)
Definition: index.h:316
HERMES_DEVICE_CALLABLE const Index2< T > & lower() const
Definition: index.h:344
HERMES_DEVICE_CALLABLE Index2Range(Index2< T > lower, Index2< T > upper)
Constructs an index range [lower, upper)
Definition: index.h:312
HERMES_DEVICE_CALLABLE friend Index2Range< T > intersect(const Index2Range< T > &a, const Index2Range< T > &b)
Definition: index.h:291
HERMES_DEVICE_CALLABLE Index2Iterator< T > begin() const
Definition: index.h:336
HERMES_DEVICE_CALLABLE Index2Iterator< T > end() const
Definition: index.h:340
HERMES_DEVICE_CALLABLE Index3Iterator & operator++()
Definition: index.h:487
HERMES_DEVICE_CALLABLE bool operator==(const Index3Iterator< T > &other) const
are equal? operator
Definition: index.h:505
HERMES_DEVICE_CALLABLE bool operator!=(const Index3Iterator< T > &other) const
are different? operator
Definition: index.h:511
HERMES_DEVICE_CALLABLE size_t flatIndex() const
Computes a flat index based on size.
Definition: index.h:481
HERMES_DEVICE_CALLABLE Index3Iterator(Index3< T > lower, Index3< T > upper, Index3< T > start)
Construct a new Index3Iterator object.
Definition: index.h:465
HERMES_DEVICE_CALLABLE const Index3< T > & operator*() const
Definition: index.h:474
HERMES_DEVICE_CALLABLE Index3Iterator(Index3< T > upper)
Definition: index.h:468
Represents a closed-open range of indices [lower, upper),.
Definition: index.h:532
HERMES_DEVICE_CALLABLE Index3Iterator< T > end() const
Definition: index.h:594
HERMES_DEVICE_CALLABLE Index3Range(size3 upper)
Definition: index.h:568
HERMES_DEVICE_CALLABLE Index3Iterator< T > begin() const
Definition: index.h:590
HERMES_DEVICE_CALLABLE size3 size() const
Definition: index.h:599
HERMES_DEVICE_CALLABLE friend Index3Range< T > intersect(const Index3Range< T > &a, const Index3Range< T > &b)
Definition: index.h:541
HERMES_DEVICE_CALLABLE size_t flatIndex(const Index3< T > &ijk) const
Computes a flat index based on size.
Definition: index.h:585
HERMES_DEVICE_CALLABLE Index3Range(Index3< T > lower, Index3< T > upper)
Definition: index.h:573
HERMES_DEVICE_CALLABLE Index3Range(Index3< T > upper)
Construct a new Index3Range object.
Definition: index.h:565
HERMES_DEVICE_CALLABLE Index3Range(T upper_i, T upper_j, T upper_k)
Construct a new Index3Range object.
Definition: index.h:561
Holds 2-dimensional size.
Definition: size.h:47
T height
1-th dimension size
Definition: size.h:133
T width
0-th dimension size
Definition: size.h:132
Holds 2-dimensional size.
Definition: size.h:142
Debug, logging and assertion macros.
#define HERMES_UNUSED_VARIABLE(x)
Specifies that variable is not used in this scope.
Definition: debug.h:62
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
#define HERMES_NOT_IMPLEMENTED
Logs "calling code not implemented" warning.
Definition: debug.h:67
#define ARITHMETIC_OP(OP)
asd
Definition: index.h:408
Set of multi-dimensional size representations.
Holds 2-dimensional integer index coordinates.
Definition: index.h:50
HERMES_DEVICE_CALLABLE Index2()
Default constructor.
Definition: index.h:102
HERMES_DEVICE_CALLABLE void clampTo(const size2 &s)
Clamps to the inclusive range [0, size]
Definition: index.h:187
T i
0-th coordinate value
Definition: index.h:199
T j
1-th coordinate value
Definition: index.h:201
HERMES_DEVICE_CALLABLE Index2(T v)
Constructor.
Definition: index.h:105
HERMES_DEVICE_CALLABLE Index2< T > left(T d=T(1)) const
Generates a copy with i decremented by d
Definition: index.h:172
HERMES_DEVICE_CALLABLE friend T distance(const Index2< T > &a, const Index2< T > &b)
Computes the manhattan distance between two indices.
Definition: index.h:79
HERMES_DEVICE_CALLABLE Index2(const Size2< S > &size)
Constructor from a Size2 object.
Definition: index.h:115
HERMES_DEVICE_CALLABLE Index2< T > right(T d=T(1)) const
Generates a copy with i incremented by d
Definition: index.h:176
HERMES_DEVICE_CALLABLE T & operator[](int d)
Definition: index.h:129
HERMES_DEVICE_CALLABLE Index2< T > down(T d=T(1)) const
Generates a copy with j decremented by d
Definition: index.h:180
HERMES_DEVICE_CALLABLE Index2< T > up(T d=T(1)) const
Generates a copy with j incremented by d
Definition: index.h:184
HERMES_DEVICE_CALLABLE Index2(T i, T j)
Constructor.
Definition: index.h:109
HERMES_DEVICE_CALLABLE Index2< T > plus(T _i, T _j) const
Generates an index with incremented values.
Definition: index.h:168
HERMES_DEVICE_CALLABLE T operator[](int d) const
Definition: index.h:124
Holds 3-dimensional index coordinates.
Definition: index.h:362
HERMES_DEVICE_CALLABLE T operator[](int _i) const
Definition: index.h:401
T k
2-th coordinate value
Definition: index.h:448
HERMES_DEVICE_CALLABLE Index3(T i, T j, T k)
Construct a new Index2 object.
Definition: index.h:392
T j
1-th coordinate value
Definition: index.h:446
HERMES_DEVICE_CALLABLE Index3(T v)
Definition: index.h:387
HERMES_DEVICE_CALLABLE T & operator[](int _i)
Definition: index.h:406
T i
0-th coordinate value
Definition: index.h:444