Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt simd adj diff #5580

Merged
merged 9 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libs/core/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ set(algorithms_headers
hpx/parallel/algorithms/copy.hpp
hpx/parallel/algorithms/count.hpp
hpx/parallel/algorithms/destroy.hpp
hpx/parallel/algorithms/detail/adjacent_difference.hpp
hpx/parallel/algorithms/detail/accumulate.hpp
hpx/parallel/algorithms/detail/advance_and_get_distance.hpp
hpx/parallel/algorithms/detail/advance_to_sentinel.hpp
Expand Down Expand Up @@ -141,6 +142,7 @@ set(algorithms_headers
hpx/parallel/container_numeric.hpp
hpx/parallel/datapar.hpp
hpx/parallel/datapar/fill.hpp
hpx/parallel/datapar/adjacent_difference.hpp
hpx/parallel/datapar/iterator_helpers.hpp
hpx/parallel/datapar/loop.hpp
hpx/parallel/datapar/transfer.hpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <hpx/iterator_support/zip_iterator.hpp>

#include <hpx/executors/execution_policy.hpp>
#include <hpx/parallel/algorithms/detail/adjacent_difference.hpp>
#include <hpx/parallel/algorithms/detail/dispatch.hpp>
#include <hpx/parallel/util/detail/algorithm_result.hpp>
#include <hpx/parallel/util/loop.hpp>
Expand Down Expand Up @@ -47,7 +48,7 @@ namespace hpx { namespace parallel { inline namespace v1 {
static OutIter sequential(
ExPolicy, InIter first, InIter last, OutIter dest, Op&& op)
{
return std::adjacent_difference(
return sequential_adjacent_difference<ExPolicy>(
first, last, dest, std::forward<Op>(op));
}

Expand Down Expand Up @@ -83,7 +84,7 @@ namespace hpx { namespace parallel { inline namespace v1 {
// VS2015RC bails out when op is captured by ref
using hpx::get;
util::loop_n<std::decay_t<ExPolicy>>(
part_begin, part_size, [op](zip_iterator it) {
part_begin, part_size, [op](auto&& it) {
get<2>(*it) =
hpx::util::invoke(op, get<0>(*it), get<1>(*it));
});
Expand Down Expand Up @@ -188,10 +189,10 @@ namespace hpx { namespace parallel { inline namespace v1 {
adjacent_difference(
ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest)
{
typedef typename std::iterator_traits<FwdIter1>::value_type value_type;
typedef hpx::traits::is_segmented_iterator<FwdIter1> is_segmented;
return detail::adjacent_difference_(std::forward<ExPolicy>(policy),
first, last, dest, std::minus<value_type>(), is_segmented());
return detail::adjacent_difference_(
std::forward<ExPolicy>(policy), first, last, dest,
[](const auto& x, const auto& y) { return x - y; }, is_segmented());
}

////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2021 Srinivas Yadav
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <hpx/config.hpp>
#include <hpx/execution/traits/is_execution_policy.hpp>
#include <hpx/functional/invoke.hpp>
#include <hpx/functional/tag_fallback_dispatch.hpp>
#include <hpx/parallel/util/loop.hpp>
#include <hpx/parallel/util/projection_identity.hpp>

#include <functional>
#include <iostream>
#include <type_traits>
#include <utility>

namespace hpx { namespace parallel { inline namespace v1 { namespace detail {

template <typename ExPolicy>
struct sequential_adjacent_difference_t
: hpx::functional::tag_fallback<
sequential_adjacent_difference_t<ExPolicy>>
{
private:
template <typename InIter, typename OutIter, typename Op>
friend inline OutIter tag_fallback_dispatch(
sequential_adjacent_difference_t<ExPolicy>, InIter first,
InIter last, OutIter dest, Op&& op)
{
return std::adjacent_difference(
first, last, dest, std::forward<Op>(op));
}
};

#if !defined(HPX_COMPUTE_DEVICE_CODE)
template <typename ExPolicy>
HPX_INLINE_CONSTEXPR_VARIABLE sequential_adjacent_difference_t<ExPolicy>
sequential_adjacent_difference =
sequential_adjacent_difference_t<ExPolicy>{};
#else
template <typename ExPolicy, typename InIter, typename OutIter, typename Op>
HPX_HOST_DEVICE HPX_FORCEINLINE OutIter sequential_adjacent_difference(
InIter first, InIter last, OutIter dest, Op&& op)
{
return sequential_adjacent_difference_t<ExPolicy>{}(
first, last, dest, std::forward<Op>(op));
}
#endif

}}}} // namespace hpx::parallel::v1::detail
1 change: 1 addition & 0 deletions libs/core/algorithms/include/hpx/parallel/datapar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#if defined(HPX_HAVE_DATAPAR)

#include <hpx/executors/datapar/execution_policy.hpp>
#include <hpx/parallel/datapar/adjacent_difference.hpp>
#include <hpx/parallel/datapar/fill.hpp>
#include <hpx/parallel/datapar/iterator_helpers.hpp>
#include <hpx/parallel/datapar/loop.hpp>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2021 Srinivas Yadav
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <hpx/config.hpp>

#if defined(HPX_HAVE_DATAPAR)
#include <hpx/concepts/concepts.hpp>
#include <hpx/execution/traits/is_execution_policy.hpp>
#include <hpx/functional/tag_dispatch.hpp>
#include <hpx/iterator_support/zip_iterator.hpp>
#include <hpx/parallel/algorithms/detail/adjacent_difference.hpp>
#include <hpx/parallel/datapar/iterator_helpers.hpp>
#include <hpx/parallel/datapar/loop.hpp>
#include <hpx/parallel/datapar/zip_iterator.hpp>
#include <hpx/parallel/util/result_types.hpp>

#include <cstddef>
#include <iostream>
#include <type_traits>
#include <utility>

namespace hpx { namespace parallel { inline namespace v1 { namespace detail {

///////////////////////////////////////////////////////////////////////////
template <typename ExPolicy>
struct datapar_adjacent_difference
{
template <typename InIter, typename OutIter, typename Op>
static inline OutIter call(
InIter first, InIter last, OutIter dest, Op&& op)
{
if (first == last)
return dest;
auto count = std::distance(first, last) - 1;

InIter prev = first;
*dest++ = *first++;

if (count == 0)
{
return dest;
}

using hpx::get;
using hpx::util::make_zip_iterator;
util::loop_n<std::decay_t<ExPolicy>>(
make_zip_iterator(first, prev, dest), count, [op](auto&& it) {
get<2>(*it) =
hpx::util::invoke(op, get<0>(*it), get<1>(*it));
});
std::advance(dest, count);
return dest;
}
};

template <typename ExPolicy, typename InIter, typename OutIter, typename Op,
HPX_CONCEPT_REQUIRES_(
hpx::is_vectorpack_execution_policy<ExPolicy>::value&&
hpx::parallel::util::detail::iterator_datapar_compatible<
InIter>::value)>
inline OutIter tag_dispatch(sequential_adjacent_difference_t<ExPolicy>,
InIter first, InIter last, OutIter dest, Op&& op)
{
return datapar_adjacent_difference<ExPolicy>::call(
first, last, dest, std::forward<Op>(op));
}
}}}} // namespace hpx::parallel::v1::detail
#endif
2 changes: 0 additions & 2 deletions libs/core/algorithms/tests/unit/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ endforeach()
# add tests
set(tests
adjacentdifference
adjacentdifference_exception
adjacentdifference_bad_alloc
adjacentfind
adjacentfind_exception
adjacentfind_bad_alloc
Expand Down
82 changes: 39 additions & 43 deletions libs/core/algorithms/tests/unit/algorithms/adjacentdifference.cpp
Original file line number Diff line number Diff line change
@@ -1,73 +1,69 @@
// Copyright (c) 2021 Srinivas Yadav
// Copyright (c) 2015 Daniel Bourgeois
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <hpx/local/init.hpp>
#include <hpx/modules/testing.hpp>
#include <hpx/parallel/algorithms/adjacent_difference.hpp>

#include <cstddef>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>

#include "test_utils.hpp"
#include "adjacentdifference_tests.hpp"

////////////////////////////////////////////////////////////////////////////
template <typename ExPolicy>
void test_adjacent_difference(ExPolicy policy)
void adjacent_difference_test()
{
static_assert(hpx::is_execution_policy<ExPolicy>::value,
"hpx::is_execution_policy<ExPolicy>::value");
using namespace hpx::execution;
test_adjacent_difference(seq);
test_adjacent_difference(par);
test_adjacent_difference(par_unseq);

std::vector<std::size_t> c = test::random_iota(10007);
std::vector<std::size_t> d(10007);
std::vector<std::size_t> d_ans(10007);
test_adjacent_difference_async(seq(task));
test_adjacent_difference_async(par(task));
}

auto it = hpx::parallel::adjacent_difference(
policy, std::begin(c), std::end(c), std::begin(d));
std::adjacent_difference(std::begin(c), std::end(c), std::begin(d_ans));
template <typename IteratorTag>
void test_adjacent_difference_exception()
{
using namespace hpx::execution;

HPX_TEST(std::equal(std::begin(d), std::end(d), std::begin(d_ans),
[](std::size_t lhs, std::size_t rhs) -> bool { return lhs == rhs; }));
// If the execution policy object is of type vector_execution_policy,
// std::terminate shall be called. therefore we do not test exceptions
// with a vector execution policy
test_adjacent_difference_exception(seq, IteratorTag());
test_adjacent_difference_exception(par, IteratorTag());

HPX_TEST(std::end(d) == it);
test_adjacent_difference_exception_async(seq(task), IteratorTag());
test_adjacent_difference_exception_async(par(task), IteratorTag());
}

template <typename ExPolicy>
void test_adjacent_difference_async(ExPolicy p)
void adjacent_difference_exception_test()
{
static_assert(hpx::is_execution_policy<ExPolicy>::value,
"hpx::is_execution_policy<ExPolicy>::value");

std::vector<std::size_t> c = test::random_iota(10007);
std::vector<std::size_t> d(10007);
std::vector<std::size_t> d_ans(10007);
test_adjacent_difference_exception<std::random_access_iterator_tag>();
test_adjacent_difference_exception<std::forward_iterator_tag>();
}

auto f_it = hpx::parallel::adjacent_difference(
p, std::begin(c), std::end(c), std::begin(d));
std::adjacent_difference(std::begin(c), std::end(c), std::begin(d_ans));
template <typename IteratorTag>
void test_adjacent_difference_bad_alloc()
{
using namespace hpx::execution;

f_it.wait();
HPX_TEST(std::equal(std::begin(d), std::end(d), std::begin(d_ans),
[](std::size_t lhs, std::size_t rhs) -> bool { return lhs == rhs; }));
// If the execution policy object is of type vector_execution_policy,
// std::terminate shall be called. therefore we do not test exceptions
// with a vector execution policy
test_adjacent_difference_bad_alloc(seq, IteratorTag());
test_adjacent_difference_bad_alloc(par, IteratorTag());

HPX_TEST(std::end(d) == f_it.get());
test_adjacent_difference_bad_alloc_async(seq(task), IteratorTag());
test_adjacent_difference_bad_alloc_async(par(task), IteratorTag());
}

void adjacent_difference_test()
void adjacent_difference_bad_alloc_test()
{
using namespace hpx::execution;
test_adjacent_difference(seq);
test_adjacent_difference(par);
test_adjacent_difference(par_unseq);

test_adjacent_difference_async(seq(task));
test_adjacent_difference_async(par(task));
test_adjacent_difference_bad_alloc<std::random_access_iterator_tag>();
test_adjacent_difference_bad_alloc<std::forward_iterator_tag>();
}

int hpx_main(hpx::program_options::variables_map& vm)
Expand Down
Loading