Skip to content

Commit

Permalink
team-level stdalgos: improve tests, check intra-team result matching …
Browse files Browse the repository at this point in the history
…(part 2/7) (kokkos#6426)

* std_algos: improving min, max, minmax

* improve tests

* forgot to reset to auto

* fix for OpenMPTarget

* fix openmptarget

* revert files to dvelop version since they are not handled in this PR
  • Loading branch information
fnrizzi committed Sep 19, 2023
1 parent d8fa856 commit 3cd2813
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ struct TestFunctorA {
template <class MemberType>
KOKKOS_INLINE_FUNCTION void operator()(const MemberType& member) const {
const auto myRowIndex = member.league_rank();

auto myRowViewFrom = Kokkos::subview(m_dataView, myRowIndex, Kokkos::ALL());
ptrdiff_t resultDist = 0;

Expand Down
32 changes: 26 additions & 6 deletions algorithms/unit_tests/TestStdAlgorithmsTeamCount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,34 @@ namespace TeamCount {

namespace KE = Kokkos::Experimental;

template <class ViewType, class ValuesViewType, class CountsViewType>
template <class ViewType, class ValuesViewType, class CountsViewType,
class IntraTeamSentinelView>
struct TestFunctorA {
ViewType m_view;
ValuesViewType m_valuesView;
CountsViewType m_countsView;
IntraTeamSentinelView m_intraTeamSentinelView;
int m_apiPick;

TestFunctorA(const ViewType view, const ValuesViewType valuesView,
const CountsViewType countsView, int apiPick)
const CountsViewType countsView,
const IntraTeamSentinelView intraTeamSentinelView, int apiPick)
: m_view(view),
m_valuesView(valuesView),
m_countsView(countsView),
m_intraTeamSentinelView(intraTeamSentinelView),
m_apiPick(apiPick) {}

template <class MemberType>
KOKKOS_INLINE_FUNCTION void operator()(const MemberType& member) const {
const auto rowIndex = member.league_rank();
const auto value = m_valuesView(rowIndex);
auto rowView = Kokkos::subview(m_view, rowIndex, Kokkos::ALL());
std::size_t result = 0;

switch (m_apiPick) {
case 0: {
auto result =
result =
KE::count(member, KE::cbegin(rowView), KE::cend(rowView), value);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_countsView(rowIndex) = result; });
Expand All @@ -53,13 +58,22 @@ struct TestFunctorA {
}

case 1: {
auto result = KE::count(member, rowView, value);
result = KE::count(member, rowView, value);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_countsView(rowIndex) = result; });

break;
}
}

// store result of checking if all members have their local
// values matching the one stored in m_distancesView
member.team_barrier();
const bool intraTeamCheck = team_members_have_matching_result(
member, result, m_countsView(rowIndex));
Kokkos::single(Kokkos::PerTeam(member), [=, *this]() {
m_intraTeamSentinelView(rowIndex) = intraTeamCheck;
});
}
};

Expand Down Expand Up @@ -123,15 +137,19 @@ void test_A(const bool searched_value_exist, std::size_t numTeams,
// to verify that things work, each team stores the result of its count
// call, and then we check that these match what we expect
Kokkos::View<std::size_t*> countsView("countsView", numTeams);
// sentinel to check if all members of the team compute the same result
Kokkos::View<bool*> intraTeamSentinelView("intraTeamSameResult", numTeams);

// use CTAD for functor
TestFunctorA fnc(dataView, valuesView, countsView, apiId);
TestFunctorA fnc(dataView, valuesView, countsView, intraTeamSentinelView,
apiId);
Kokkos::parallel_for(policy, fnc);

// -----------------------------------------------
// check
// -----------------------------------------------
auto countsView_h = create_host_space_copy(countsView);
auto countsView_h = create_host_space_copy(countsView);
auto intraTeamSentinelView_h = create_host_space_copy(intraTeamSentinelView);
if (searched_value_exist) {
for (std::size_t i = 0; i < dataView.extent(0); ++i) {
auto rowFrom = Kokkos::subview(dataViewBeforeOp_h, i, Kokkos::ALL());
Expand All @@ -141,11 +159,13 @@ void test_A(const bool searched_value_exist, std::size_t numTeams,

const std::size_t result = std::count(rowFromBegin, rowFromEnd, val);
ASSERT_EQ(result, countsView_h(i));
ASSERT_TRUE(intraTeamSentinelView_h(i));
}
} else {
for (std::size_t i = 0; i < countsView.extent(0); ++i) {
constexpr std::size_t zero = 0;
ASSERT_EQ(countsView_h(i), zero);
ASSERT_TRUE(intraTeamSentinelView_h(i));
}
}
}
Expand Down
31 changes: 25 additions & 6 deletions algorithms/unit_tests/TestStdAlgorithmsTeamCountIf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,51 @@ struct GreaterThanValueFunctor {
bool operator()(ValueType val) const { return (val > m_val); }
};

template <class ViewType, class CountsViewType, class ValueType>
template <class ViewType, class CountsViewType, class IntraTeamSentinelView,
class ValueType>
struct TestFunctorA {
ViewType m_view;
CountsViewType m_countsView;
IntraTeamSentinelView m_intraTeamSentinelView;
ValueType m_threshold;
int m_apiPick;

TestFunctorA(const ViewType view, const CountsViewType countsView,
const IntraTeamSentinelView intraTeamSentinelView,
ValueType threshold, int apiPick)
: m_view(view),
m_countsView(countsView),
m_intraTeamSentinelView(intraTeamSentinelView),
m_threshold(threshold),
m_apiPick(apiPick) {}

template <class MemberType>
KOKKOS_INLINE_FUNCTION void operator()(const MemberType& member) const {
const auto myRowIndex = member.league_rank();
auto myRowView = Kokkos::subview(m_view, myRowIndex, Kokkos::ALL());
std::size_t myCount = 0;

GreaterThanValueFunctor predicate(m_threshold);
if (m_apiPick == 0) {
auto myCount = KE::count_if(member, KE::begin(myRowView),
KE::end(myRowView), predicate);
myCount = KE::count_if(member, KE::begin(myRowView), KE::end(myRowView),
predicate);

Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_countsView(myRowIndex) = myCount; });
} else if (m_apiPick == 1) {
auto myCount = KE::count_if(member, myRowView, predicate);
myCount = KE::count_if(member, myRowView, predicate);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_countsView(myRowIndex) = myCount; });
}

// store result of checking if all members have their local
// values matching the one stored in m_distancesView
member.team_barrier();
const bool intraTeamCheck = team_members_have_matching_result(
member, myCount, m_countsView(myRowIndex));
Kokkos::single(Kokkos::PerTeam(member), [=, *this]() {
m_intraTeamSentinelView(myRowIndex) = intraTeamCheck;
});
}
};

Expand Down Expand Up @@ -101,15 +115,19 @@ void test_A(std::size_t numTeams, std::size_t numCols, int apiId) {
// of its count_if call, and then we check
// that these match what we expect
Kokkos::View<std::size_t*> countsView("countsView", numTeams);
// sentinel to check if all members of the team compute the same result
Kokkos::View<bool*> intraTeamSentinelView("intraTeamSameResult", numTeams);

// use CTAD for functor
TestFunctorA fnc(dataView, countsView, threshold, apiId);
TestFunctorA fnc(dataView, countsView, intraTeamSentinelView, threshold,
apiId);
Kokkos::parallel_for(policy, fnc);

// -----------------------------------------------
// check
// -----------------------------------------------
auto countsView_h = create_host_space_copy(countsView);
auto countsView_h = create_host_space_copy(countsView);
auto intraTeamSentinelView_h = create_host_space_copy(intraTeamSentinelView);
for (std::size_t i = 0; i < cloneOfDataViewBeforeOp_h.extent(0); ++i) {
std::size_t goldCountForRow = 0;
for (std::size_t j = 0; j < cloneOfDataViewBeforeOp_h.extent(1); ++j) {
Expand All @@ -118,6 +136,7 @@ void test_A(std::size_t numTeams, std::size_t numCols, int apiId) {
}
}
ASSERT_EQ(goldCountForRow, countsView_h(i));
ASSERT_TRUE(intraTeamSentinelView_h(i));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,23 @@ struct LessFunctor {
};

template <class DataViewType, class CompViewType, class ResultsViewType,
class BinaryCompType>
class IntraTeamSentinelView, class BinaryCompType>
struct TestFunctorA {
DataViewType m_dataView;
CompViewType m_compView;
ResultsViewType m_resultsView;
IntraTeamSentinelView m_intraTeamSentinelView;
int m_apiPick;
BinaryCompType m_binaryComp;

TestFunctorA(const DataViewType dataView, const CompViewType compView,
const ResultsViewType resultsView, int apiPick,
const ResultsViewType resultsView,
const IntraTeamSentinelView intraTeamSentinelView, int apiPick,
BinaryCompType binaryComp)
: m_dataView(dataView),
m_compView(compView),
m_resultsView(resultsView),
m_intraTeamSentinelView(intraTeamSentinelView),
m_apiPick(apiPick),
m_binaryComp(binaryComp) {}

Expand All @@ -62,39 +65,48 @@ struct TestFunctorA {
const auto compBegin = KE::cbegin(rowComp);
const auto compEnd = KE::cend(rowComp);

bool result = false;
switch (m_apiPick) {
case 0: {
const bool result = KE::lexicographical_compare(
member, dataBegin, dataEnd, compBegin, compEnd);
result = KE::lexicographical_compare(member, dataBegin, dataEnd,
compBegin, compEnd);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_resultsView(rowIndex) = result; });
break;
}

case 1: {
const bool result =
KE::lexicographical_compare(member, rowData, rowComp);
result = KE::lexicographical_compare(member, rowData, rowComp);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_resultsView(rowIndex) = result; });
break;
}

case 2: {
const bool result = KE::lexicographical_compare(
member, dataBegin, dataEnd, compBegin, compEnd, m_binaryComp);
result = KE::lexicographical_compare(member, dataBegin, dataEnd,
compBegin, compEnd, m_binaryComp);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_resultsView(rowIndex) = result; });
break;
}

case 3: {
const bool result =
result =
KE::lexicographical_compare(member, rowData, rowComp, m_binaryComp);
Kokkos::single(Kokkos::PerTeam(member),
[=, *this]() { m_resultsView(rowIndex) = result; });
break;
}
}

// store result of checking if all members have their local
// values matching the one stored in m_distancesView
member.team_barrier();
const bool intraTeamCheck = team_members_have_matching_result(
member, result, m_resultsView(rowIndex));
Kokkos::single(Kokkos::PerTeam(member), [=, *this]() {
m_intraTeamSentinelView(rowIndex) = intraTeamCheck;
});
}
};

Expand Down Expand Up @@ -161,17 +173,21 @@ void test_A(const TestCaseType testCase, std::size_t numTeams,

// create the view to store results of equal()
Kokkos::View<bool*> resultsView("resultsView", numTeams);
// sentinel to check if all members of the team compute the same result
Kokkos::View<bool*> intraTeamSentinelView("intraTeamSameResult", numTeams);

LessFunctor<ValueType> binaryComp{};

// use CTAD for functor
TestFunctorA fnc(dataView, compEqualView, resultsView, apiId, binaryComp);
TestFunctorA fnc(dataView, compEqualView, resultsView, intraTeamSentinelView,
apiId, binaryComp);
Kokkos::parallel_for(policy, fnc);

// -----------------------------------------------
// run cpp-std kernel and check
// -----------------------------------------------
auto resultsView_h = create_host_space_copy(resultsView);
auto resultsView_h = create_host_space_copy(resultsView);
auto intraTeamSentinelView_h = create_host_space_copy(intraTeamSentinelView);

for (std::size_t i = 0; i < dataView.extent(0); ++i) {
auto rowData = Kokkos::subview(dataViewBeforeOp_h, i, Kokkos::ALL());
Expand All @@ -182,6 +198,7 @@ void test_A(const TestCaseType testCase, std::size_t numTeams,
const auto compBegin = KE::cbegin(rowComp);
const auto compEnd = KE::cend(rowComp);

ASSERT_TRUE(intraTeamSentinelView_h(i));
switch (apiId) {
case 0:
case 1: {
Expand Down

0 comments on commit 3cd2813

Please sign in to comment.