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

Relocation algorithms Clean #6314

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
2709dd9
relocate_at impl w/ tests
isidorostsa Jul 27, 2023
3afc851
uninitialized_relocate w/ tests and comments fixed
isidorostsa Jul 28, 2023
0b3a6e8
expected compile error tests
isidorostsa Jul 28, 2023
fe6e0fb
clang-format
isidorostsa Jul 28, 2023
8ef523a
add explicit-noexcept where it is missing
isidorostsa Jul 29, 2023
13a1279
enum instead of magic numbers
isidorostsa Jul 29, 2023
2c9edb0
remove explicit from move constructors
isidorostsa Jul 30, 2023
36b70cb
add explicit to relocate_at.cpp too
isidorostsa Jul 30, 2023
148d729
fix Werror=class-memaccess, cast away const
isidorostsa Jul 31, 2023
cafae0c
clang-format
isidorostsa Jul 31, 2023
bf48827
too long line
isidorostsa Aug 1, 2023
2706778
clang-format
isidorostsa Aug 1, 2023
07bd94c
Arrays of TR types are TR
isidorostsa Jul 11, 2023
6f22033
is_trivially_copyable -> is_trivially_relocatable correction
isidorostsa Jul 11, 2023
cb44e29
Add cvrefs and arrays to be "decayed"
isidorostsa Jul 13, 2023
7fb8958
arrays of known size
isidorostsa Jul 13, 2023
3f6059d
const volatile to avoid ambiguity
isidorostsa Jul 26, 2023
4367007
cover rvalues too
isidorostsa Jul 26, 2023
6dcb771
clang format
isidorostsa Jul 27, 2023
6e532e1
testing and more specific ambiguity checks
isidorostsa Jul 28, 2023
18705b9
clang-format
isidorostsa Jul 31, 2023
22aeff9
clang-format
isidorostsa Aug 6, 2023
944ccb9
detect trivially relocatable category
isidorostsa Aug 11, 2023
7dbc69e
specific loop version needed for relocations
isidorostsa Aug 11, 2023
ba51777
uninitialized_relocate helpers
isidorostsa Aug 11, 2023
b41893f
deprecate type_support/uninitialized_relocate.hpp
isidorostsa Aug 11, 2023
87f68e1
algorithms/uninitialized_relocate.hpp seq version
isidorostsa Aug 11, 2023
ab55350
algorithms/uninitialized_relocate.hpp par version
isidorostsa Aug 11, 2023
324c3f1
various syntax fixes
isidorostsa Aug 13, 2023
8d126a3
uninitialized_relocate_n test
isidorostsa Aug 21, 2023
b2f3946
include is_relocatable
isidorostsa Aug 21, 2023
40269c0
missing includes and namespaces
isidorostsa Aug 21, 2023
312cf1f
fix includes
isidorostsa Aug 22, 2023
b30eb55
fix typo + include
isidorostsa Aug 22, 2023
8685988
endline
isidorostsa Aug 22, 2023
2c1f407
remove circ dep
isidorostsa Aug 22, 2023
9b27231
correctly resolve namespaces
isidorostsa Aug 22, 2023
db65f32
change uninitialzied_relocate_n test name
isidorostsa Aug 22, 2023
8f0cc63
uninitialized_relocate iterators version
isidorostsa Aug 22, 2023
6e1e85e
add noexcept relocation detector
isidorostsa Aug 22, 2023
db8ed7c
use HPX_CONCEPT_REQUIRES, detect noexcepts
isidorostsa Aug 22, 2023
a3d51bf
fix returned value of nothrow relocation
isidorostsa Aug 22, 2023
00fb2e5
clang-format
isidorostsa Aug 22, 2023
0d3d917
clang-format
isidorostsa Aug 22, 2023
0d3a178
inspect
isidorostsa Aug 22, 2023
0a60cf8
Merge branch 'relocate_algorithms_clean' of github.com:isidorostsa/hp…
isidorostsa Aug 22, 2023
1a2e8a7
remove unneeded params + clang-format
isidorostsa Aug 22, 2023
99c4dbb
using execution_policy instead of hpx/execution
isidorostsa Aug 22, 2023
36080a3
include fixes
isidorostsa Aug 22, 2023
a9f9e9a
remove unused var
isidorostsa Aug 23, 2023
32ed3c1
unwrap zip_iterator manually
isidorostsa Aug 23, 2023
c288589
clang-format
isidorostsa Aug 23, 2023
95a70a0
gcc11 fix unpacking iterators
isidorostsa Aug 23, 2023
4b98351
clang-format
isidorostsa Aug 24, 2023
909998c
Add doxygen docs
isidorostsa Aug 24, 2023
4bdc115
clang-format
isidorostsa Aug 24, 2023
1e57fe5
docs typo
isidorostsa Aug 24, 2023
426c52a
EOF endline
isidorostsa Aug 24, 2023
8fd47df
public api gives better warnings
isidorostsa Aug 25, 2023
d26c2f6
atomics in test
isidorostsa Sep 7, 2023
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
1 change: 1 addition & 0 deletions libs/core/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ set(algorithms_headers
hpx/parallel/algorithms/uninitialized_default_construct.hpp
hpx/parallel/algorithms/uninitialized_fill.hpp
hpx/parallel/algorithms/uninitialized_move.hpp
hpx/parallel/algorithms/uninitialized_relocate.hpp
hpx/parallel/algorithms/uninitialized_value_construct.hpp
hpx/parallel/algorithms/unique.hpp
hpx/parallel/container_algorithms/adjacent_difference.hpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <hpx/iterator_support/traits/is_iterator.hpp>
#include <hpx/type_support/is_relocatable.hpp>
#include <hpx/type_support/is_trivially_relocatable.hpp>

#include <type_traits>

Expand All @@ -25,7 +26,11 @@ namespace hpx::traits {
{
};

struct relocatable_pointer_tag : general_pointer_tag
struct trivially_relocatable_pointer_tag : general_pointer_tag
{
};

struct nothrow_relocatable_pointer_tag : general_pointer_tag
{
};

Expand Down Expand Up @@ -139,20 +144,34 @@ namespace hpx::traits {
using type = general_pointer_tag;
};

template <typename Source, typename Dest,
bool Contiguous = iterators_are_contiguous_v<Source, Dest>>
template <typename Source, typename Dest>
struct pointer_relocate_category
{
using type = std::conditional_t<
std::is_same_v<iter_value_t<Source>, iter_value_t<Dest>> &&
is_relocatable_v<iter_value_t<Source>>,
relocatable_pointer_tag, general_pointer_tag>;
};
using type_src = iter_value_t<Source>;
using type_dst = iter_value_t<Dest>;

template <typename Source, typename Dest>
struct pointer_relocate_category<Source, Dest, false>
{
using type = general_pointer_tag;
constexpr static bool valid_relocation =
is_relocatable_from_v<type_src, type_dst>;

constexpr static bool memcpy_legal =
!std::is_volatile_v<type_src> && !std::is_volatile_v<type_dst>;

constexpr static bool is_buffer_memcpyable = valid_relocation &&
is_trivially_relocatable_v<type_src> &&
iterators_are_contiguous_v<Source, Dest> && memcpy_legal;

constexpr static bool can_move_construct_nothrow =
std::is_nothrow_constructible_v<type_src,
std::add_rvalue_reference_t<type_dst>>;

// Used externally to determine if a relocation is noexcept
constexpr static bool is_noexcept_relocatable_v =
can_move_construct_nothrow && is_buffer_memcpyable;

using type = std::conditional_t<is_buffer_memcpyable,
trivially_relocatable_pointer_tag,
std::conditional_t<can_move_construct_nothrow,
nothrow_relocatable_pointer_tag, general_pointer_tag>>;
};
} // namespace detail

Expand Down

Large diffs are not rendered by default.

171 changes: 171 additions & 0 deletions libs/core/algorithms/include/hpx/parallel/util/loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <hpx/assert.hpp>
#include <hpx/datastructures/tuple.hpp>
#include <hpx/execution/traits/is_execution_policy.hpp>
#include <hpx/executors/execution_policy.hpp>
#include <hpx/functional/detail/invoke.hpp>
#include <hpx/functional/detail/tag_fallback_invoke.hpp>
#include <hpx/functional/invoke_result.hpp>
Expand Down Expand Up @@ -781,6 +782,176 @@ namespace hpx::parallel::util {
dest, tok, HPX_FORWARD(F, f), HPX_FORWARD(Cleanup, cleanup));
}

namespace detail {
// Helper class to repeatedly call a function a given number of times
// starting from a given iterator position. The cleanup function is
// called with an argument of the iterator that was being processed
// when the exception was thrown.
struct loop_with_manual_cleanup_n final
: hpx::functional::detail::tag_fallback<loop_with_manual_cleanup_n>
{
template <typename ExPolicy, typename FwdIter, typename F,
typename Cleanup>
static FwdIter call(ExPolicy&&, FwdIter it, std::size_t num, F&& f,
Cleanup&& cleanup)
{
try
{
std::size_t count(num & std::size_t(-4)); // -V112
for (std::size_t i = 0; i < count;
(void) ++it, i += 4) // -V112
{
HPX_INVOKE(f, it);
HPX_INVOKE(f, ++it);
HPX_INVOKE(f, ++it);
HPX_INVOKE(f, ++it);
}
for (/**/; count < num; (void) ++count, ++it)
{
HPX_INVOKE(f, it);
}
return it;
}
catch (...)
{
// Give the user the flexibility to
// clean up whichever iterators they want
// only providing the iterator that
// was being processed when the exception
// was thrown
HPX_INVOKE(cleanup, it);
throw;
}
}

// Manual cleanup
template <typename ExPolicy, typename FwdIter, typename F,
typename Cleanup>
friend HPX_HOST_DEVICE HPX_FORCEINLINE FwdIter tag_fallback_invoke(
loop_with_manual_cleanup_n, ExPolicy&& policy, FwdIter it,
std::size_t num, F&& f, Cleanup&& cleanup)
{
return call(HPX_FORWARD(ExPolicy, policy), it, num,
HPX_FORWARD(F, f), HPX_FORWARD(Cleanup, cleanup));
}

// Manual cleanup with token
template <typename ExPolicy, typename FwdIter, typename CancelToken,
typename F, typename Cleanup>
HPX_HOST_DEVICE HPX_FORCEINLINE static FwdIter call_with_token(
ExPolicy&& policy, FwdIter it, std::size_t num,
CancelToken& tok, F&& f, Cleanup&& cleanup)
{
// check at the start of a partition only
if (tok.was_cancelled())
return it;

return call(HPX_FORWARD(ExPolicy, policy), it, num,
HPX_FORWARD(F, f), HPX_FORWARD(Cleanup, cleanup));
}

// Manual cleanup
template <typename ExPolicy, typename FwdIter, typename F,
typename Cleanup>
static FwdIter unseq_call(
ExPolicy, FwdIter it, std::size_t num, F&& f, Cleanup&& cleanup)
{
try
{
std::size_t count(num & std::size_t(-4)); // -V112

// clang-format off
HPX_IVDEP HPX_UNROLL HPX_VECTORIZE
for (std::size_t i = 0; i < count;
(void) ++it, ++i) // -V112
{
HPX_INVOKE(f, it);
}

HPX_IVDEP HPX_UNROLL HPX_VECTORIZE
for (/**/; count < num; (void) ++count, ++it)
{
HPX_INVOKE(f, it);
}
// clang-format on

return it;
}
catch (...)
{
// Give the user the flexibility to
// clean up whichever iterators they want
// only providing the iterator that
// was being processed when the exception
// was thrown
HPX_INVOKE(cleanup, it);
throw;
}
}

}; // struct loop_with_manual_cleanup_n

}; // namespace detail

#if !defined(HPX_COMPUTE_DEVICE_CODE)
inline constexpr detail::loop_with_manual_cleanup_n
loop_with_manual_cleanup_n = detail::loop_with_manual_cleanup_n{};
#else
template <typename ExPolicy, typename Begin, typename F, typename Cleanup>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr Begin loop_with_manual_cleanup_n(
ExPolicy&& policy, Begin begin, std::size_t n, F&& f, Cleanup&& cleanup)
{
return hpx::parallel::util::detail::loop_with_manual_cleanup_n{}(
HPX_FORWARD(ExPolicy, policy), begin, n, HPX_FORWARD(F, f),
HPX_FORWARD(Cleanup, cleanup));
}
#endif

template <typename Begin, typename F, typename Cleanup>
HPX_HOST_DEVICE HPX_FORCEINLINE Begin tag_invoke(
hpx::parallel::util::detail::loop_with_manual_cleanup_n,
hpx::execution::unsequenced_policy, Begin HPX_RESTRICT begin,
std::size_t n, F&& f, Cleanup&& cleanup)
{
return hpx::parallel::util::detail::loop_with_manual_cleanup_n::
unseq_call(
begin, n, HPX_FORWARD(F, f), HPX_FORWARD(Cleanup, cleanup));
}

template <typename Begin, typename F, typename Cleanup>
HPX_HOST_DEVICE HPX_FORCEINLINE Begin tag_invoke(
hpx::parallel::util::detail::loop_with_manual_cleanup_n,
hpx::execution::unsequenced_task_policy, Begin HPX_RESTRICT begin,
std::size_t n, F&& f, Cleanup&& cleanup)
{
return hpx::parallel::util::detail::loop_with_manual_cleanup_n::
unseq_call(
begin, n, HPX_FORWARD(F, f), HPX_FORWARD(Cleanup, cleanup));
}

template <typename Iter, typename CancelToken, typename F, typename Cleanup,
HPX_CONCEPT_REQUIRES_(hpx::traits::is_iterator_v<Iter>)>
HPX_FORCEINLINE constexpr Iter loop_with_manual_cleanup_n_with_token(
Iter it, std::size_t count, CancelToken& tok, F&& f, Cleanup&& cleanup)
{
return detail::loop_with_manual_cleanup_n::call_with_token(
::hpx::execution::seq, it, count, tok, HPX_FORWARD(F, f),
HPX_FORWARD(Cleanup, cleanup));
}

template <typename ExPolicy, typename Iter, typename CancelToken,
typename F, typename Cleanup,
HPX_CONCEPT_REQUIRES_(hpx::is_execution_policy_v<ExPolicy>&&
hpx::traits::is_iterator_v<Iter>)> // could be a zip iterator
HPX_FORCEINLINE constexpr Iter loop_with_manual_cleanup_n_with_token(
ExPolicy&& policy, Iter it, std::size_t count, CancelToken& tok, F&& f,
Cleanup&& cleanup)
{
return detail::loop_with_manual_cleanup_n::call_with_token(
HPX_FORWARD(ExPolicy, policy), it, count, tok, HPX_FORWARD(F, f),
HPX_FORWARD(Cleanup, cleanup));
}

///////////////////////////////////////////////////////////////////////////
namespace detail {

Expand Down
Loading