RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
RangeSegment.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_RangeSegment_HPP
21 #define RAJA_RangeSegment_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include <iostream>
26 
28 
29 #include "RAJA/util/concepts.hpp"
30 
32 
33 namespace RAJA
34 {
35 
97 template<typename StorageT,
98  typename DiffT = make_signed_t<strip_index_type_t<StorageT>>>
100 {
101 
102  //
103  // Static asserts to provide some useful error messages during compilation
104  // for incorrect usage.
105  //
106  static_assert(std::is_signed<DiffT>::value,
107  "TypedRangeSegment DiffT requires signed type.");
108  static_assert(!std::is_floating_point<StorageT>::value,
109  "TypedRangeSegment Type must be non floating point.");
110 
112 
116 
118  using value_type = StorageT;
119 
121  using IndexType = DiffT;
122 
124 
126 
135 
138  : m_begin(iterator(begin)),
139  m_end(begin > end ? m_begin : iterator(end))
140  {}
141 
144 
146  constexpr TypedRangeSegment(TypedRangeSegment&&) = default;
147 
149  constexpr TypedRangeSegment(TypedRangeSegment const&) = default;
150 
152  RAJA_INLINE TypedRangeSegment& operator=(TypedRangeSegment const&) = default;
153 
155  RAJA_INLINE ~TypedRangeSegment() = default;
156 
158 
160 
165  RAJA_HOST_DEVICE RAJA_INLINE iterator begin() const { return m_begin; }
166 
170  RAJA_HOST_DEVICE RAJA_INLINE iterator end() const { return m_end; }
171 
175  RAJA_HOST_DEVICE RAJA_INLINE DiffT size() const { return m_end - m_begin; }
176 
178 
180 
187  RAJA_HOST_DEVICE RAJA_INLINE bool operator==(TypedRangeSegment const& o) const
188  {
189  // someday this shall be replaced with a compiler-generated operator==
190  return m_begin == o.m_begin && m_end == o.m_end;
191  }
192 
198  RAJA_HOST_DEVICE RAJA_INLINE bool operator!=(TypedRangeSegment const& o) const
199  {
200  return !(operator==(o));
201  }
202 
204 
228  DiffT length) const
229  {
230  StorageT start = m_begin[0] + begin;
231  StorageT end = start + length > m_end[0] ? m_end[0] : start + length;
232 
234  }
235 
239  RAJA_HOST_DEVICE RAJA_INLINE void swap(TypedRangeSegment& other)
240  {
241  camp::safe_swap(m_begin, other.m_begin);
242  camp::safe_swap(m_end, other.m_end);
243  }
244 
245 private:
246  // Member variable for begin iterator
247  iterator m_begin;
248 
249  // Member variable for end iterator
250  iterator m_end;
251 };
252 
330 template<typename StorageT,
331  typename DiffT = make_signed_t<strip_index_type_t<StorageT>>>
333 {
334 
335  //
336  // Static asserts to provide some useful error messages during compilation
337  // for incorrect usage.
338  //
339  static_assert(std::is_signed<DiffT>::value,
340  "TypedRangeStrideSegment DiffT requires signed type.");
341  static_assert(!std::is_floating_point<StorageT>::value,
342  "TypedRangeStrideSegment Type must be non floating point.");
343 
345 
349 
351  using value_type = StorageT;
352 
354  using IndexType = DiffT;
355 
357 
359 
370 
373  DiffT stride)
374  : m_begin(iterator(begin, stride)),
375  m_end(iterator(end, stride)),
376  // essentially a ceil((end-begin)/stride) but using integer math,
377  // and allowing for negative strides
378  m_size((end - begin + stride - (stride > 0 ? 1 : -1)) / stride)
379  {
380  // clamp range when end is unreachable from begin without wrapping
381  if (stride < 0 && end > begin)
382  {
383  m_end = m_begin;
384  }
385  else if (stride > 0 && end < begin)
386  {
387  m_end = m_begin;
388  }
389  // m_size initialized as negative indicates a zero iteration space
390  m_size = m_size < DiffT {0} ? DiffT {0} : m_size;
391  }
392 
395 
398 
401 
404 
407 
409 
411 
416  RAJA_HOST_DEVICE iterator begin() const { return m_begin; }
417 
421  RAJA_HOST_DEVICE iterator end() const { return m_end; }
422 
429  RAJA_HOST_DEVICE DiffT size() const { return m_size; }
430 
432 
434 
442  {
443  // someday this shall be replaced with a compiler-generated operator==
444  return m_begin == o.m_begin && m_end == o.m_end && m_size == o.m_size;
445  }
446 
452  RAJA_HOST_DEVICE RAJA_INLINE bool operator!=(
453  TypedRangeStrideSegment const& o) const
454  {
455  return !(operator==(o));
456  }
457 
459 
487  DiffT length) const
488  {
489  StorageT stride = m_begin.get_stride();
490  StorageT start = m_begin[0] + begin * stride;
491  StorageT end = start + stride * length;
492 
493  if (stride > 0)
494  {
495  end = end > m_end[0] ? m_end[0] : end;
496  }
497  else
498  {
499  end = end < m_end[0] ? m_end[0] : end;
500  }
501 
503  m_begin.get_stride()};
504  }
505 
510  {
511  camp::safe_swap(m_begin, other.m_begin);
512  camp::safe_swap(m_end, other.m_end);
513  camp::safe_swap(m_size, other.m_size);
514  }
515 
516 private:
517  // Member variable for begin iterator
518  iterator m_begin;
519 
520  // Member variable for end iterator
521  iterator m_end;
522 
523  // Member variable for size of segment
524  DiffT m_size;
525 };
526 
529 
532 
533 namespace detail
534 {
535 
536 template<typename T, typename... Rest>
538  : std::common_type<T, typename std::common_type<Rest...>::type>
539 {};
540 
541 template<typename T>
542 struct common_type<T>
543 {
544  using type = T;
545 };
546 
547 template<typename... Ts>
548 using common_type_t = typename common_type<Ts...>::type;
549 
550 } // namespace detail
551 
560 template<typename BeginT,
561  typename EndT,
562  typename Common = detail::common_type_t<BeginT, EndT>>
564  EndT&& end)
565 {
566  return {begin, end};
567 }
568 
578 template<typename BeginT,
579  typename EndT,
580  typename StrideT,
581  typename Common = detail::common_type_t<BeginT, EndT>>
583  BeginT&& begin,
584  EndT&& end,
585  StrideT&& stride)
586 {
587  static_assert(std::is_signed<StrideT>::value,
588  "make_strided_segment : stride must be signed.");
589  static_assert(
590  std::is_same<make_signed_t<EndT>, StrideT>::value,
591  "make_stride_segment : stride and end must be of similar types.");
592  return {begin, end, stride};
593 }
594 
595 namespace concepts
596 {
597 
598 template<typename T, typename U>
600  : DefineConcept(camp::val<RAJA::detail::common_type_t<T, U>>()) {};
601 
602 template<typename T, typename U, typename V>
604  : DefineConcept(camp::val<RAJA::detail::common_type_t<T, U, V>>()) {};
605 
606 } // namespace concepts
607 
608 namespace type_traits
609 {
610 
611 DefineTypeTraitFromConcept(is_range_constructible,
613 
614 DefineTypeTraitFromConcept(is_range_stride_constructible,
616 
617 } // namespace type_traits
618 
619 } // namespace RAJA
620 
621 namespace std
622 {
623 
625 template<typename T>
628 {
629  a.swap(b);
630 }
631 
633 template<typename T>
636 {
637  a.swap(b);
638 }
639 
640 } // namespace std
641 
642 #endif // closing endif for header file include guard
RAJA header file for strongly-typed integer class.
Header file for RAJA iterator constructs.
Definition: Iterators.hpp:114
Definition: Iterators.hpp:304
RAJA_HOST_DEVICE DifferenceType get_stride() const
Definition: Iterators.hpp:330
Header file for RAJA concept definitions.
#define RAJA_HOST_DEVICE
Definition: macros.hpp:65
typename common_type< Ts... >::type common_type_t
Definition: RangeSegment.hpp:548
DefineTypeTraitFromConcept(is_range_constructible, RAJA::concepts::RangeConstructible)
Definition: AlignedRangeIndexSetBuilders.cpp:35
typename internal::StripIndexTypeT< FROM >::type strip_index_type_t
Strips a strongly typed index to its underlying type In the case of a non-strongly typed index,...
Definition: IndexValue.hpp:364
RAJA_HOST_DEVICE TypedRangeStrideSegment< Common > make_strided_range(BeginT &&begin, EndT &&end, StrideT &&stride)
Function to make a TypedRangeStride Segment for the interval [begin, end) with given stride.
Definition: RangeSegment.hpp:582
constexpr RAJA_HOST_DEVICE RAJA_INLINE std::enable_if< std::is_base_of< IndexValueBase, FROM >::value, typename FROM::value_type >::type stripIndexType(FROM const val)
Function that strips the strongly typed Index<> and returns its underlying value_type value.
Definition: IndexValue.hpp:323
RAJA_HOST_DEVICE TypedRangeSegment< Common > make_range(BeginT &&begin, EndT &&end)
Function to make a TypedRangeSegment for the interval [begin, end)
Definition: RangeSegment.hpp:563
typename std::conditional< std::is_floating_point< FROM >::value, std::common_type< FROM >, std::make_signed< FROM > >::type::type make_signed_t
Converts a type into a signed type. Also handles floating point types as std::make_signed only suppor...
Definition: IndexValue.hpp:376
Definition: ListSegment.hpp:416
RAJA_INLINE void swap(RAJA::TypedListSegment< StorageT > &a, RAJA::TypedListSegment< StorageT > &b)
Specialization of std::swap for TypedListSegment.
Definition: ListSegment.hpp:420
Segment class representing a contiguous range of typed indices.
Definition: RangeSegment.hpp:100
DiffT IndexType
The underlying type for a difference in index values.
Definition: RangeSegment.hpp:121
RAJA_HOST_DEVICE RAJA_INLINE bool operator!=(TypedRangeSegment const &o) const
Compare this segment to another for inequality.
Definition: RangeSegment.hpp:198
RAJA_INLINE TypedRangeSegment & operator=(TypedRangeSegment const &)=default
Defaulted copy assignment operator.
strip_index_type_t< StorageT > StripStorageT
Construct a range segment repreenting the interval [begin, end)
Definition: RangeSegment.hpp:134
Iterators::numeric_iterator< StorageT, DiffT > iterator
The underlying iterator type.
Definition: RangeSegment.hpp:115
RAJA_HOST_DEVICE RAJA_INLINE DiffT size() const
Get size of this segment (end - begin)
Definition: RangeSegment.hpp:175
RAJA_HOST_DEVICE RAJA_INLINE iterator end() const
Get iterator to the end of this segment.
Definition: RangeSegment.hpp:170
RAJA_HOST_DEVICE RAJA_INLINE iterator begin() const
Get iterator to the beginning of this segment.
Definition: RangeSegment.hpp:165
RAJA_HOST_DEVICE RAJA_INLINE TypedRangeSegment slice(StorageT begin, DiffT length) const
Get a new TypedRangeSegment instance representing a slice of existing segment.
Definition: RangeSegment.hpp:227
constexpr RAJA_HOST_DEVICE TypedRangeSegment(StripStorageT begin, StripStorageT end)
Definition: RangeSegment.hpp:136
RAJA_HOST_DEVICE RAJA_INLINE bool operator==(TypedRangeSegment const &o) const
Compare this segment to another for equality.
Definition: RangeSegment.hpp:187
constexpr TypedRangeSegment(TypedRangeSegment &&)=default
Defaulted move constructor.
RAJA_HOST_DEVICE RAJA_INLINE void swap(TypedRangeSegment &other)
Swap this segment with another.
Definition: RangeSegment.hpp:239
RAJA_HOST_DEVICE TypedRangeSegment()=delete
Disable compiler generated constructor.
constexpr TypedRangeSegment(TypedRangeSegment const &)=default
Defaulted copy constructor.
RAJA_INLINE ~TypedRangeSegment()=default
Defaulted destructor.
StorageT value_type
The underlying value type.
Definition: RangeSegment.hpp:118
Segment class representing a strided range of typed indices.
Definition: RangeSegment.hpp:333
strip_index_type_t< StorageT > StripStorageT
Construct a range segment for the interval [begin, end) with given stride.
Definition: RangeSegment.hpp:369
RAJA_HOST_DEVICE iterator begin() const
Get iterator to the beginning of this segment.
Definition: RangeSegment.hpp:416
TypedRangeStrideSegment(TypedRangeStrideSegment &&)=default
Defaulted move constructor.
StorageT value_type
The underlying value type.
Definition: RangeSegment.hpp:351
Iterators::strided_numeric_iterator< StorageT, DiffT > iterator
The underlying iterator type.
Definition: RangeSegment.hpp:348
RAJA_HOST_DEVICE TypedRangeStrideSegment slice(StorageT begin, DiffT length) const
Get a new TypedRangeStrideSegment instance representing a slice of existing segment.
Definition: RangeSegment.hpp:486
RAJA_HOST_DEVICE RAJA_INLINE bool operator!=(TypedRangeStrideSegment const &o) const
Compare this segment to another for inequality.
Definition: RangeSegment.hpp:452
~TypedRangeStrideSegment()=default
Defaulted destructore.
RAJA_HOST_DEVICE bool operator==(TypedRangeStrideSegment const &o) const
Compare this segment to another for equality.
Definition: RangeSegment.hpp:441
RAJA_HOST_DEVICE void swap(TypedRangeStrideSegment &other)
Swap this segment with another.
Definition: RangeSegment.hpp:509
TypedRangeStrideSegment()=delete
Disable compiler generated constructor.
TypedRangeStrideSegment(TypedRangeStrideSegment const &)=default
Defaulted copy constructor.
RAJA_HOST_DEVICE iterator end() const
Get iterator to the end of this segment.
Definition: RangeSegment.hpp:421
DiffT IndexType
The underlying type for a difference in index values.
Definition: RangeSegment.hpp:354
RAJA_HOST_DEVICE DiffT size() const
Get size of this segment.
Definition: RangeSegment.hpp:429
TypedRangeStrideSegment & operator=(TypedRangeStrideSegment const &)=default
Defaulted copy assignment operator.
RAJA_HOST_DEVICE TypedRangeStrideSegment(StripStorageT begin, StripStorageT end, DiffT stride)
Definition: RangeSegment.hpp:371
Definition: RangeSegment.hpp:600
Definition: RangeSegment.hpp:604
T type
Definition: RangeSegment.hpp:544
Definition: RangeSegment.hpp:539