diff --git a/libs/core/algorithms/include/hpx/parallel/algorithms/uninitialized_relocate.hpp b/libs/core/algorithms/include/hpx/parallel/algorithms/uninitialized_relocate.hpp index 40a046f270da..7b26c506bd87 100644 --- a/libs/core/algorithms/include/hpx/parallel/algorithms/uninitialized_relocate.hpp +++ b/libs/core/algorithms/include/hpx/parallel/algorithms/uninitialized_relocate.hpp @@ -393,7 +393,7 @@ namespace hpx { #include #include #include -#include +#include #include #include @@ -739,10 +739,37 @@ namespace hpx::experimental { FwdIter>::get(HPX_MOVE(dest)); } + // If running in non-sequenced execution policy, we must check + // that the ranges are not overlapping in the left + if constexpr (!hpx::is_sequenced_execution_policy_v) + { + // if we can check for overlapping ranges + if constexpr (hpx::traits::is_contiguous_iterator_v && + hpx::traits::is_contiguous_iterator_v) + { + auto dest_last = std::next(dest, count); + auto last = std::next(first, count); + // if it is not overlapping in the left direction + if (!((first < dest_last) && (dest_last < last))) + { + // use parallel version + return parallel::util::get_second_element( + hpx::parallel::detail::uninitialized_relocate_n< + parallel::util::in_out_result>() + .call(HPX_FORWARD(ExPolicy, policy), first, + count, dest)); + } + // if it is we continue to use the sequential version + } + // else we assume that the ranges are overlapping, and continue + // to use the sequential version + } + return parallel::util::get_second_element( hpx::parallel::detail::uninitialized_relocate_n< parallel::util::in_out_result>() - .call(HPX_FORWARD(ExPolicy, policy), first, + .call(hpx::execution::seq, first, static_cast(count), dest)); } } uninitialized_relocate_n{}; @@ -825,10 +852,37 @@ namespace hpx::experimental { FwdIter>::get(HPX_MOVE(dest)); } + // If running in non-sequenced execution policy, we must check + // that the ranges are not overlapping in the left + if constexpr (!hpx::is_sequenced_execution_policy_v) + { + // if we can check for overlapping ranges + if constexpr (hpx::traits::is_contiguous_iterator_v && + hpx::traits::is_contiguous_iterator_v) + { + auto dest_last = std::next(dest, count); + // if it is not overlapping in the left direction + if (!((first < dest_last) && (dest_last < last))) + { + // use parallel version + return parallel::util::get_second_element( + hpx::parallel::detail::uninitialized_relocate_n< + parallel::util::in_out_result>() + .call(HPX_FORWARD(ExPolicy, policy), first, + count, dest)); + } + // if it is we continue to use the sequential version + } + // else we assume that the ranges are overlapping, and continue + // to use the sequential version + } + + // sequential execution policy return parallel::util::get_second_element( hpx::parallel::detail::uninitialized_relocate_n< parallel::util::in_out_result>() - .call(HPX_FORWARD(ExPolicy, policy), first, count, dest)); + .call(hpx::execution::seq, first, count, dest)); } } uninitialized_relocate{}; @@ -897,12 +951,6 @@ namespace hpx::experimental { "Relocating from this source type to this destination type is " "ill-formed"); - if constexpr (!hpx::is_sequenced_execution_policy_v) - { - /*What should go here?*/ - static_assert(false); - } - auto count = std::distance(first, last); // if count is representing a negative value, we do nothing @@ -912,11 +960,37 @@ namespace hpx::experimental { BiIter2>::get(HPX_MOVE(dest_last)); } + // If running in non-sequence execution policy, we must check + // that the ranges are not overlapping in the right + if constexpr (!hpx::is_sequenced_execution_policy_v) + { + // if we can check for overlapping ranges + if constexpr (hpx::traits::is_contiguous_iterator_v && + hpx::traits::is_contiguous_iterator_v) + { + auto dest_first = std::prev(dest_last, count); + // if it is not overlapping in the right direction + if (!((first < dest_first) && (dest_first < last))) + { + // use parallel version + return parallel::util::get_second_element( + hpx::parallel::detail:: + uninitialized_relocate_backward>() + .call(HPX_FORWARD(ExPolicy, policy), first, + last, dest_last)); + } + // if it is we continue to use the sequential version + } + // else we assume that the ranges are overlapping, and continue + // to use the sequential version + } + + // sequential execution policy return parallel::util::get_second_element( hpx::parallel::detail::uninitialized_relocate_backward< parallel::util::in_out_result>() - .call( - HPX_FORWARD(ExPolicy, policy), first, last, dest_last)); + .call(hpx::execution::seq, first, last, dest_last)); } } uninitialized_relocate_backward{}; } // namespace hpx::experimental diff --git a/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate.cpp b/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate.cpp index 864edfb25080..e612ff1773c9 100644 --- a/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate.cpp +++ b/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate.cpp @@ -361,13 +361,11 @@ void test() return; } -// template -// void test_overlapping(Ex&& ex) +template void test_overlapping() { - using Ex = hpx::execution::sequenced_policy; - - static_assert(std::is_same_v); + // using Ex = hpx::execution::sequenced_policy; + // static_assert(std::is_same_v); constexpr int offset = 4; @@ -515,7 +513,8 @@ int hpx_main() test(); test(); - test_overlapping(); + test_overlapping(); + test_overlapping(); return hpx::local::finalize(); } diff --git a/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate_backward.cpp b/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate_backward.cpp index aef16e247da7..04fea6e3f3bd 100644 --- a/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate_backward.cpp +++ b/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocate_backward.cpp @@ -361,13 +361,11 @@ void test() return; } -// template -// void test_overlapping(Ex&& ex) +template void test_overlapping() { - using Ex = hpx::execution::sequenced_policy; - - static_assert(std::is_same_v); + // using Ex = hpx::execution::sequenced_policy; + // static_assert(std::is_same_v); constexpr int offset = 4; @@ -514,7 +512,8 @@ int hpx_main() test(); test(); - test_overlapping(); + test_overlapping(); + test_overlapping(); return hpx::local::finalize(); } diff --git a/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocaten.cpp b/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocaten.cpp index 65dbad00aae3..68fc92aecfdf 100644 --- a/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocaten.cpp +++ b/libs/core/algorithms/tests/unit/algorithms/uninitialized_relocaten.cpp @@ -361,13 +361,11 @@ void test() return; } -// template -// void test_overlapping(Ex&& ex) +template void test_overlapping() { - using Ex = hpx::execution::sequenced_policy; - - static_assert(std::is_same_v); + // using Ex = hpx::execution::sequenced_policy; + // static_assert(std::is_same_v); constexpr int offset = 4; @@ -515,7 +513,8 @@ int hpx_main() test(); test(); - test_overlapping(); + test_overlapping(); + test_overlapping(); return hpx::local::finalize(); }