Skip to content

Commit 6bd2d1d

Browse files
authored
Add equal to mhp and shp (#802)
1 parent 43dbd47 commit 6bd2d1d

27 files changed

+316
-103
lines changed

include/dr/mhp.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include <dr/mhp/views/mdspan_view.hpp>
6666
#include <dr/mhp/views/submdspan_view.hpp>
6767
#include <dr/mhp/algorithms/copy.hpp>
68+
#include <dr/mhp/algorithms/equal.hpp>
6869
#include <dr/mhp/algorithms/fill.hpp>
6970
#include <dr/mhp/algorithms/for_each.hpp>
7071
#include <dr/mhp/algorithms/exclusive_scan.hpp>

include/dr/mhp/algorithms/equal.hpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// SPDX-FileCopyrightText: Intel Corporation
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#pragma once
6+
#include <concepts>
7+
#include <dr/concepts/concepts.hpp>
8+
#include <dr/mhp/algorithms/reduce.hpp>
9+
#include <dr/mhp/algorithms/transform.hpp>
10+
#include <dr/mhp/views/zip.hpp>
11+
12+
namespace dr::mhp::_detail {
13+
template <dr::distributed_range R1, dr::distributed_range R2>
14+
requires std::equality_comparable_with<rng::range_value_t<R1>,
15+
rng::range_value_t<R2>>
16+
bool equal(std::size_t root, bool root_provided, R1 &&r1, R2 &&r2) {
17+
18+
if (rng::distance(r1) != rng::distance(r2)) {
19+
return false;
20+
}
21+
22+
// we must use ints instead of bools, because distributed ranges do not
23+
// support bools
24+
auto compare = [](auto &&elems) {
25+
return elems.first == elems.second ? 1 : 0;
26+
};
27+
28+
auto zipped_views = views::zip(r1, r2);
29+
30+
// we are using mhp::transform instead of mhp::views::transform due to
31+
// compilation error refer to DRA-192 and test/gtest/mhp/reduce.cpp
32+
mhp::distributed_vector<int> compared(rng::distance(r1));
33+
mhp::transform(zipped_views, compared.begin(), compare);
34+
35+
auto min = [](double x, double y) { return std::min(x, y); };
36+
if (root_provided) {
37+
auto result = mhp::reduce(root, compared, 1, min);
38+
return result == 1;
39+
}
40+
auto result = mhp::reduce(compared, 1, min);
41+
return result == 1;
42+
}
43+
44+
} // namespace dr::mhp::_detail
45+
46+
namespace dr::mhp {
47+
template <dr::distributed_range R1, dr::distributed_range R2>
48+
requires std::equality_comparable_with<rng::range_value_t<R1>,
49+
rng::range_value_t<R2>>
50+
bool equal(std::size_t root, R1 &&r1, R2 &&r2) {
51+
return _detail::equal(root, true, r1, r2);
52+
}
53+
54+
template <dr::distributed_range R1, dr::distributed_range R2>
55+
requires std::equality_comparable_with<rng::range_value_t<R1>,
56+
rng::range_value_t<R2>>
57+
bool equal(R1 &&r1, R2 &&r2) {
58+
return _detail::equal(0, false, r1, r2);
59+
}
60+
61+
} // namespace dr::mhp

include/dr/mhp/algorithms/reduce.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ auto reduce(std::size_t root, bool root_provided, DR &&dr, auto &&binary_op) {
103103
template <typename T, dr::distributed_range DR>
104104
T reduce(std::size_t root, bool root_provided, DR &&dr, T init,
105105
auto &&binary_op = std::plus<>{}) {
106+
107+
if (rng::empty(dr)) {
108+
return init;
109+
}
106110
return binary_op(init, reduce(root, root_provided, dr, binary_op));
107111
}
108112

include/dr/shp/algorithms/algorithms.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include <dr/shp/algorithms/copy.hpp>
8+
#include <dr/shp/algorithms/equal.hpp>
89
#include <dr/shp/algorithms/exclusive_scan.hpp>
910
#include <dr/shp/algorithms/execution_policy.hpp>
1011
#include <dr/shp/algorithms/fill.hpp>

include/dr/shp/algorithms/equal.hpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-FileCopyrightText: Intel Corporation
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#pragma once
6+
7+
#include <dr/shp/algorithms/fill.hpp>
8+
#include <dr/shp/algorithms/reduce.hpp>
9+
#include <dr/shp/detail.hpp>
10+
#include <dr/shp/init.hpp>
11+
#include <dr/shp/util.hpp>
12+
#include <dr/shp/views/views.hpp>
13+
#include <dr/shp/zip_view.hpp>
14+
15+
namespace dr::shp {
16+
17+
template <typename ExecutionPolicy, dr::distributed_range R1,
18+
dr::distributed_range R2>
19+
requires std::equality_comparable_with<rng::range_value_t<R1>,
20+
rng::range_value_t<R2>>
21+
bool equal(ExecutionPolicy &&policy, R1 &&r1, R2 &&r2) {
22+
23+
if (rng::distance(r1) != rng::distance(r2)) {
24+
return false;
25+
}
26+
27+
// we must use ints instead of bools, because distributed ranges do not
28+
// support bools
29+
auto compare = [](auto &&elems) {
30+
return elems.first == elems.second ? 1 : 0;
31+
};
32+
33+
auto zipped_views = views::zip(r1, r2);
34+
auto compared = shp::views::transform(zipped_views, compare);
35+
auto min = [](double x, double y) { return std::min(x, y); };
36+
auto result = shp::reduce(policy, compared, 1, min);
37+
return result == 1;
38+
}
39+
40+
template <dr::distributed_range R1, dr::distributed_range R2>
41+
bool equal(R1 &&r1, R2 &&r2) {
42+
return equal(dr::shp::par_unseq, r1, r2);
43+
}
44+
} // namespace dr::shp

include/dr/views/transform.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class transform_iterator {
118118
};
119119

120120
template <rng::random_access_range V, std::copy_constructible F>
121+
requires(std::is_default_constructible_v<F>)
121122
class transform_view : public rng::view_interface<transform_view<V, F>> {
122123
public:
123124
template <rng::viewable_range R>

test/gtest/common/equal.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// SPDX-FileCopyrightText: Intel Corporation
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#include "xhp-tests.hpp"
6+
7+
// Fixture
8+
template <typename T> class Equals : public testing::Test {
9+
public:
10+
};
11+
12+
TYPED_TEST_SUITE(Equals, AllTypes);
13+
14+
TYPED_TEST(Equals, Same) {
15+
Ops1<TypeParam> ops(10);
16+
17+
xhp::distributed_vector<int> toCompareXhp(10);
18+
19+
for (std::size_t idx = 0; idx < 10; idx++) {
20+
toCompareXhp[idx] = ops.dist_vec[idx];
21+
}
22+
barrier();
23+
24+
bool xhpEq = xhp::equal(ops.dist_vec, toCompareXhp);
25+
26+
EXPECT_TRUE(xhpEq);
27+
}
28+
29+
TYPED_TEST(Equals, Different) {
30+
Ops1<TypeParam> ops(10);
31+
32+
xhp::distributed_vector<int> toCompareXhp(10);
33+
34+
for (std::size_t idx = 0; idx < 10; idx++) {
35+
toCompareXhp[idx] = ops.dist_vec[idx];
36+
}
37+
38+
toCompareXhp[2] = ops.dist_vec[2] + 1;
39+
40+
barrier();
41+
42+
bool xhpEq = xhp::equal(ops.dist_vec, toCompareXhp);
43+
44+
EXPECT_TRUE(!xhpEq);
45+
}
46+
47+
TYPED_TEST(Equals, EmptiesEqual) {
48+
Ops1<TypeParam> ops(0);
49+
50+
xhp::distributed_vector<int> toCompareXhp(0);
51+
52+
bool xhpEq = xhp::equal(ops.dist_vec, toCompareXhp);
53+
54+
EXPECT_TRUE(xhpEq);
55+
}
56+
57+
TYPED_TEST(Equals, EmptyNotEmptyDifferent) {
58+
Ops1<TypeParam> ops(0);
59+
60+
xhp::distributed_vector<int> toCompareXhp(10);
61+
62+
bool xhpEq = xhp::equal(ops.dist_vec, toCompareXhp);
63+
64+
EXPECT_TRUE(!xhpEq);
65+
}

test/gtest/common/for_each.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void test_foreach_n(std::vector<T> v, int n, int initial_skip, auto func) {
2222
xhp::for_each_n(d_v.begin() + initial_skip, n, func);
2323
rng::for_each_n(v.begin() + initial_skip, n, func);
2424

25-
EXPECT_TRUE(equal(v, d_v));
25+
EXPECT_TRUE(equal_gtest(v, d_v));
2626
}
2727

2828
TYPED_TEST_SUITE(ForEach, AllTypes);

test/gtest/common/iota.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ TYPED_TEST(IotaTest, SlicedLeft) {
3333
TypeParam dist_vec(10, 0);
3434
xhp::iota(dist_vec.begin() + 2, dist_vec.end(), 2);
3535
EXPECT_TRUE(
36-
equal(dist_vec, LocalVec<TypeParam>{0, 0, 2, 3, 4, 5, 6, 7, 8, 9}));
36+
equal_gtest(dist_vec, LocalVec<TypeParam>{0, 0, 2, 3, 4, 5, 6, 7, 8, 9}));
3737
}
3838

3939
TYPED_TEST(IotaTest, SlicedRight) {
4040
TypeParam dist_vec(10, 0);
4141
xhp::iota(dist_vec.begin(), dist_vec.end() - 2, 2);
4242
EXPECT_TRUE(
43-
equal(dist_vec, LocalVec<TypeParam>{2, 3, 4, 5, 6, 7, 8, 9, 0, 0}));
43+
equal_gtest(dist_vec, LocalVec<TypeParam>{2, 3, 4, 5, 6, 7, 8, 9, 0, 0}));
4444
}
4545

4646
TYPED_TEST(IotaTest, Large) {

test/gtest/common/iota_view.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ TYPED_TEST(IotaView, ZipWithDR) {
2121
dve = ve;
2222
});
2323

24-
EXPECT_TRUE(equal(std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, dv));
24+
EXPECT_TRUE(equal_gtest(std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, dv));
2525
}
2626

2727
TYPED_TEST(IotaView, Copy) {
@@ -31,7 +31,7 @@ TYPED_TEST(IotaView, Copy) {
3131
xhp::copy(v, dv.begin());
3232

3333
barrier();
34-
EXPECT_TRUE(equal(std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, dv));
34+
EXPECT_TRUE(equal_gtest(std::vector<int>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, dv));
3535
}
3636

3737
TYPED_TEST(IotaView, Transform) {
@@ -41,8 +41,8 @@ TYPED_TEST(IotaView, Transform) {
4141

4242
xhp::transform(v, dv.begin(), negate);
4343

44-
EXPECT_TRUE(
45-
equal(dv, std::vector<int>{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
44+
EXPECT_TRUE(equal_gtest(
45+
dv, std::vector<int>{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
4646
}
4747

4848
TYPED_TEST(IotaView, ForEach) {
@@ -58,6 +58,6 @@ TYPED_TEST(IotaView, ForEach) {
5858

5959
xhp::for_each(z, negate);
6060

61-
EXPECT_TRUE(
62-
equal(dv, std::vector<int>{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
61+
EXPECT_TRUE(equal_gtest(
62+
dv, std::vector<int>{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
6363
}

0 commit comments

Comments
 (0)