DASH  0.3.0
Equal.h
1 #ifndef DASH__ALGORITHM__EQUAL_H__
2 #define DASH__ALGORITHM__EQUAL_H__
3 
4 #include <dash/algorithm/LocalRange.h>
5 #include <dash/algorithm/Operation.h>
7 #include <dash/iterator/GlobIter.h>
8 
9 namespace dash {
10 namespace internal {
11  template<typename Ptr>
12  inline char equal_loc_impl(
13  const Ptr & l_first_1,
14  const Ptr & l_last_1,
15  const Ptr & l_first_2){
16  return static_cast<char>(std::equal(l_first_1, l_last_1, l_first_2));
17  }
18  template<typename Ptr, typename BinaryPredicate>
19  inline char equal_loc_impl(
20  const Ptr & l_first_1,
21  const Ptr & l_last_1,
22  const Ptr & l_first_2,
23  BinaryPredicate pred){
24  return static_cast<char>(std::equal(l_first_1, l_last_1, l_first_2, pred));
25  }
26 
27  template<typename GlobIter>
28  char equal_overlapping_impl(
29  const GlobIter & first_1,
30  const GlobIter & last_1,
31  const GlobIter & first_2){
32  auto loc_idx_r = dash::local_index_range(first_1, last_1);
33  auto dist = loc_idx_r.end - loc_idx_r.begin;
34  auto git_beg_idx = first_1.pattern().global(loc_idx_r.begin);
35  auto offset = git_beg_idx - first_1.gpos();
36  auto glfirst_1 = first_1+offset; // globIt to first pos
37 
38  // TODO: This should work for one-local-block ranges, but does not
39  // KNOWN ISSUE
40  return std::equal(glfirst_1, glfirst_1+dist, first_2+offset);
41  }
42  } // namespace internal
43 
50  template <typename GlobIter>
51  bool equal(
53  GlobIter first_1,
55  GlobIter last_1,
56  GlobIter first_2)
57  {
58  static_assert(
60  "invalid iterator: Need to be a global iterator");
61 
62  auto& team = first_1.team();
63  auto myid = team.myid();
64  // Global iterators to local range:
65  auto index_range_in = dash::local_range(first_1, last_1);
66  auto l_first_1 = index_range_in.begin;
67  auto l_last_1 = index_range_in.end;
68  auto dist = std::distance(l_first_1, l_last_1);
69  auto index_range_out = dash::local_range(first_2, first_2 + dist);
70  auto common_dist = std::min(
71  std::distance(index_range_out.begin, index_range_out.end), dist);
72  char l_result = 1;
73 
74  // check if local ranges are corresponding
75  if (common_dist == dist) {
76  l_result = ::dash::internal::equal_loc_impl(
77  l_first_1, l_last_1, first_2.local());
78  } else if(common_dist > 0) {
79  l_result = ::dash::internal::equal_overlapping_impl(
80  first_1, last_1, first_2);
81  }
82 
83  char r_result = 0;
84 
85  DASH_ASSERT_RETURNS(
86  dart_allreduce(&l_result, &r_result, 1,
87  DART_TYPE_BYTE, DART_OP_BAND, team.dart_id()),
88  DART_OK);
89  return r_result;
90 }
91 
99 template <typename GlobIter, class BinaryPredicate>
100 bool equal(
102  GlobIter first_1,
104  GlobIter last_1,
105  GlobIter first_2,
106  BinaryPredicate /*pred*/)
107 {
108  static_assert(
110  "invalid iterator: Need to be a global iterator");
111 
112  auto & team = first_1.team();
113  auto myid = team.myid();
114  // Global iterators to local range:
115  auto index_range_in = dash::local_range(first_1, last_1);
116  auto l_first_1 = index_range_in.begin;
117  auto l_last_1 = index_range_in.end;
118  auto dist = std::distance(l_first_1, l_last_1);
119  auto index_range_out = dash::local_range(first_2, first_2 + dist);
120  auto common_dist = std::min(std::distance(index_range_out.begin, index_range_out.end),dist);
121  char l_result = 1;
122 
123  // check if local ranges are corresponding
124  if(std::distance(index_range_out.begin, index_range_out.end) == dist){
125  l_result = ::dash::internal::equal_loc_impl(l_first_1, l_last_1, first_2.local());
126  } else if(common_dist > 0) {
127  l_result = ::dash::internal::equal_overlapping_impl(
128  first_1, last_1, first_2);
129  }
130 
131  char r_result = 0;
132 
133  DASH_ASSERT_RETURNS(
134  dart_allreduce(&l_result, &r_result, 1,
135  DART_TYPE_BYTE, DART_OP_BAND, team.dart_id()),
136  DART_OK);
137  return r_result;
138 }
139 
140 } // namespace dash
141 
142 #endif // DASH__ALGORITHM__EQUAL_H__
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
Signals success.
Definition: dart_types.h:33
RandomAccessIt::difference_type distance(const RandomAccessIt &first, const RandomAccessIt &last)
Resolve the number of elements between two iterators.
Definition: Iterator.h:90
bool equal(GlobIter first_1, GlobIter last_1, GlobIter first_2, BinaryPredicate)
Returns true if the range [first1, last1) is equal to the range [first2, first2 + (last1 - first1)) w...
Definition: Equal.h:100
LocalRange< const typename GlobIterType::value_type > local_range(const GlobIterType &first, const GlobIterType &last)
Resolves the local address range between global iterators.
Definition: LocalRange.h:295
DASH_CONSTEXPR local_type local() const
Convert global iterator to native pointer.
Definition: GlobIter.h:279
dart_ret_t dart_allreduce(const void *sendbuf, void *recvbuf, size_t nelem, dart_datatype_t dtype, dart_operation_t op, dart_team_t team)
DART Equivalent to MPI allreduce.
Iterator on Partitioned Global Address Space.
Definition: GlobIter.h:45
#define DART_TYPE_BYTE
integral data types
Definition: dart_types.h:125
Binary AND.
Definition: dart_types.h:83
bool equal(GlobIter first_1, GlobIter last_1, GlobIter first_2)
Returns true if the range [first1, last1) is equal to the range [first2, first2 + (last1 - first1))...
Definition: Equal.h:51
std::enable_if< !GlobInputIter::has_view::value, LocalIndexRange< typename GlobInputIter::pattern_type::index_type >>::type local_index_range(const GlobInputIter &first, const GlobInputIter &last)
Resolves the local index range between global iterators.
Definition: LocalRange.h:101